Как бороться с округлением TimeSpan? - PullRequest
6 голосов
/ 26 апреля 2010

Я беру разницу между двумя полями DateTime и сохраняю ее в переменной TimeSpan. Теперь мне нужно округлить TimeSpan по следующим правилам:

если минуты в TimeSpan меньше 30, то Minutes and Seconds должны быть установлены на ноль,
если минуты в TimeSpan равны или превышают 30, то часы должны быть увеличены на 1, а минуты и секунды должны быть установлены на ноль.

TimeSpan также может быть отрицательным значением, поэтому в этом случае мне нужно сохранить знак ..

Я мог бы выполнить требование, если бы TimeSpan не был отрицательным значением, хотя я написал код, я не доволен его неэффективностью, поскольку он более громоздкий ..

Пожалуйста, предложите мне более простой и эффективный метод.

С уважением,

Это мой код, который отлично работает, когда TimeSpan не имеет отрицательного значения ..

TimeSpan time_span = endTime.Subtract(startTime);
            TimeSpan time_span1;
            if (time_span.Minutes >= 30)
            {
                time_span1 = new TimeSpan(time_span.Hours + 1, 0, 0);
            }
            else
            {
                time_span1 = new TimeSpan(time_span.Hours, 0, 0);
            }

time_span1 будет содержать результат ..

Ответы [ 3 ]

10 голосов
/ 26 апреля 2010

Как насчет:

public static TimeSpan Round(TimeSpan input)
{
    if (input < TimeSpan.Zero)
    {
        return -Round(-input);
    }
    int hours = (int) input.TotalHours;
    if (input.Minutes >= 30)
    {
        hours++;
    }
    return TimeSpan.FromHours(hours);
}
4 голосов
/ 26 апреля 2010

Вы можете использовать

double v = span.TotalHours;     
v = Math.Round(v, MidpointRounding.AwayFromZero);
span = TimeSpan.FromHours(v);

Это зависит от того, правильно ли я понял ваши правила для отрицательных значений.

3 голосов
/ 26 апреля 2010

TimeSpan является неизменным, поэтому вы должны создать новый. Это также идеальный случай для использования методов расширения в C #:

public static class TimeSpanUtility
{
   public static TimeSpan Round( this TimeSpan ts )
   {
       var sign = ts < TimeSpan.Zero ? -1 : 1;
       var roundBy = Math.Abs(ts.Minutes) >= 30 ? 1 : 0;
       return TimeSpan.FromHours( ts.TotalHours + (sign * roundBy) );
   }
}

// usage would be:
var someTimeSpan = new TimeSpan( 2, 45, 15 );
var roundedTime = someTimeSpan.Round();
...