舍入DateTime对象

我想将date/时间四舍五入到最近的图表应用程序的时间间隔。 我想要一个扩展方法的签名,如下所示,以达到任何级别的精度四舍五入:

static DateTime Round(this DateTime date, TimeSpan span); 

这个想法是,如果我通过十分钟的时间跨度,它会四舍五入到最近的十分钟的时间间隔。 我无法理解这个实现,希望你们中的一个人能写出或使用过类似的东西。

我认为无论是楼层,天花板还是最近的实施都很好。

有任何想法吗?

编辑:感谢@tvanfosson&@SuguggyCoUk,实现如下所示:

 public static class DateExtensions { public static DateTime Round(this DateTime date, TimeSpan span) { long ticks = (date.Ticks + (span.Ticks / 2) + 1)/ span.Ticks; return new DateTime(ticks * span.Ticks); } public static DateTime Floor(this DateTime date, TimeSpan span) { long ticks = (date.Ticks / span.Ticks); return new DateTime(ticks * span.Ticks); } public static DateTime Ceil(this DateTime date, TimeSpan span) { long ticks = (date.Ticks + span.Ticks - 1) / span.Ticks; return new DateTime(ticks * span.Ticks); } } 

并被这样调用:

 DateTime nearestHour = DateTime.Now.Round(new TimeSpan(1,0,0)); DateTime minuteCeiling = DateTime.Now.Ceil(new TimeSpan(0,1,0)); DateTime weekFloor = DateTime.Now.Floor(new TimeSpan(7,0,0,0)); ... 

干杯!

地板

 long ticks = date.Ticks / span.Ticks; return new DateTime( ticks * span.Ticks ); 

回合(上中)

 long ticks = (date.Ticks + (span.Ticks / 2) + 1)/ span.Ticks; return new DateTime( ticks * span.Ticks ); 

天花板

 long ticks = (date.Ticks + span.Ticks - 1)/ span.Ticks; return new DateTime( ticks * span.Ticks ); 

这将让你轮到任何给定的时间间隔,稍快于分割,然后乘以蜱,最重要的是它是可读的。

 private static DateTime Floor(DateTime dateTime, TimeSpan interval) { return dateTime.AddTicks(-(dateTime.Ticks % interval.Ticks)); } private static DateTime Ceiling(DateTime dateTime, TimeSpan interval) { var overflow = dateTime.Ticks % interval.Ticks; return overflow == 0 ? dateTime : dateTime.AddTicks(interval.Ticks - overflow); } private static DateTime Round(DateTime dateTime, TimeSpan interval) { var halfIntervalTicks = (interval.Ticks + 1) >> 1; return dateTime.AddTicks(halfIntervalTicks - ((dateTime.Ticks + halfIntervalTicks) % interval.Ticks)); } 

你也应该清楚,如果你想四舍五入:

  1. 到区间的开始,结束或中间
    • 开始是最简单的,往往是预期的,但你应该清楚你的初始规格。
  2. 你想如何边界案件四舍五入。
    • 通常只是一个问题,如果你四舍五入到中间而不是结束。
    • 由于四舍五入的中间是一个无偏见的答案尝试,你需要使用像银行家技术圆的一半,甚至是真正摆脱偏见。

你很可能真的只关心第一点,但在这些“简单”的问题中,当你在现实世界中使用它(通常在零点附近)时,结果会产生深远的影响,

tvanfosson的解决scheme涵盖了1中列出的所有情况。中点示例偏向上。 这是一个与时间有关的问题,这是值得怀疑的。

只需使用Ticks,使用Ticks来分割,平铺/整理/舍入数值,然后再乘以。

如果你只是想把小时上限值整理一下

 Console.WriteLine(DateTime.Now.ToString("M/d/yyyy hh:00:00"));