【问题标题】:DateTime Round Up and Down日期时间向上和向下舍入
【发布时间】:2012-07-06 14:46:13
【问题描述】:

我一直在寻找一种合适的舍入机制,但我发现的似乎都不是我所需要的。

我需要分别向上和向下舍入,并且我还需要考虑已经四舍五入的情况。

我需要进行以下舍入

5:00 -> RoundDown() -> 5:00
5:04 -> RoundDown() -> 5:00
5:09 -> RoundDown() -> 5:00
5:10 -> RoundDown() -> 5:10

4:00 -> RoundUp() -> 4:00
4:50 -> RoundUp() -> 4:50
4:51 -> RoundUp() -> 5:00
4:56 -> RoundUp() -> 5:00 

基本上,我需要将 RoundUp() 或 RoundDown() 明确地精确到最近的 10 分钟,但如果时间已经是 10 分钟的倍数,它也应该保持不变。另外我想截断任何秒,以使其对舍入过程没有影响

4:50:45 -> 4:50:00 -> RoundUp() -> 4:50

有没有人有任何方便的代码来完成这个。

我在某处找到了这段代码,但它舍入 5:00 -> RoundUp() -> 5:10 而不是保持原样,因为它已经是 10 的倍数并且不需要舍入。我也不确定秒会如何影响它

public static DateTime RoundDateTime(this DateTime dt, int minutes, RoundingDirection direction)
{
    TimeSpan t;
    switch (direction)
    {
        case RoundingDirection.Up:
            t = (dt.Subtract(DateTime.MinValue)).Add(new TimeSpan(0, minutes, 0)); break;
        case RoundingDirection.Down:
            t = (dt.Subtract(DateTime.MinValue)); break;
        default:
            t = (dt.Subtract(DateTime.MinValue)).Add(new TimeSpan(0, minutes / 2, 0)); break;
    }
    return DateTime.MinValue.Add(new TimeSpan(0,
           (((int)t.TotalMinutes) / minutes) * minutes, 0));
}

希望有人可以编辑该方法以使其适合我。谢谢

【问题讨论】:

  • 好的。所以你有四舍五入的代码。您为什么不对其进行修改以使其完成您需要做的事情?
  • 您的舍入规则不清楚。你从 5:09 到 5:00,但从 4:56 到 5:00。
  • @Rawling:嗯.. 因为 5:09 被向下取整,4:56 被向上取整??
  • @mellam 天哪,我完全误读了这个问题。这没东西看! (无论如何我选择了错误的例子,我的意思是 4:51 到 5:00。)

标签: c# .net datetime rounding


【解决方案1】:

这将让您根据给定的任何间隔进行舍入。

public static class DateTimeExtensions
{
  public static DateTime Floor(this DateTime dateTime, TimeSpan interval)
  {
    return dateTime.AddTicks(-(dateTime.Ticks % interval.Ticks));
  }

  public static DateTime Ceiling(this DateTime dateTime, TimeSpan interval)
  {
    var overflow = dateTime.Ticks % interval.Ticks;

    return overflow == 0 ? dateTime : dateTime.AddTicks(interval.Ticks - overflow);
  }

  public static DateTime Round(this DateTime dateTime, TimeSpan interval)
  {
    var halfIntervalTicks = (interval.Ticks + 1) >> 1;

    return dateTime.AddTicks(halfIntervalTicks - ((dateTime.Ticks + halfIntervalTicks) % interval.Ticks));
  }
}

为了处理截断秒数,我只需从日期时间中减去秒数和毫秒数,然后再将它们发送到舍入函数。

【讨论】:

    【解决方案2】:

    怎么样:

    case RoundingDirection.Up:
        t = dt.AddMinutes((60 - dt.Minute) % 10);
    case RoundingDirection.Down:
        t = dt.AddMinutes(-dt.Minute % 10);
    

    演示:http://ideone.com/AlB7Q

    【讨论】:

    • 这样可以节省时间吗?
    【解决方案3】:

    这是一种快速截断(向下舍入)的方法

    var now = DateTime.Now;
    var nowTicks = now.Ticks;
    
    //removing the nanoseconds, miliseconds, and seconds from the nowTicks
    var lastMinute = new DateTime(nowTicks - (nowTicks % (1000*1000*10*60)));
    

    【讨论】:

      【解决方案4】:

      此函数将向上或向下舍入到最接近的间隔(分钟)。

          private static DateTime NormalizeReadingInterval(DateTime originalTime, int interval)
          {
              if (originalTime.Minute % interval == 0) return originalTime;
              var epochTime = new DateTime(1900, 1, 1);
              var minutes = (originalTime - epochTime).TotalMinutes;
              var numIntervals = minutes / interval;
              var roundedNumIntervals = Math.Round(numIntervals, 0);
              return epochTime.AddMinutes(roundedNumIntervals * interval);
          }
      

      【讨论】:

        【解决方案5】:

        另一种避免使用类型 long 进行算术运算的方法。

        使用整数除法,其中 a & b 是正整数:

        a/b             // rounding down 
        (a+b-1)/b       // rounding up 
        ((2*a)+b)/(2*b) // rounding to the nearest (0.5 up)
        

        四舍五入:

        public static DateTime UpToNearestXmin( DateTime dt, int block )
        {
           int a = dt.Minute;
           int b = block;
        
           int mins = block * (( a + b - 1 ) / b );
        
           return new DateTime( dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0 ).AddMinutes( mins );
        }
        

        要向下舍入或最接近,请根据需要更改分钟计算。

        分钟是四舍五入的。秒和毫秒归零,这是预期的行为。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多