舍入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)); }
你也应该清楚,如果你想四舍五入:
- 到区间的开始,结束或中间
- 开始是最简单的,往往是预期的,但你应该清楚你的初始规格。
- 你想如何边界案件四舍五入。
- 通常只是一个问题,如果你四舍五入到中间而不是结束。
- 由于四舍五入的中间是一个无偏见的答案尝试,你需要使用像银行家技术圆的一半,甚至是真正摆脱偏见。
你很可能真的只关心第一点,但在这些“简单”的问题中,当你在现实世界中使用它(通常在零点附近)时,结果会产生深远的影响,
tvanfosson的解决scheme涵盖了1中列出的所有情况。中点示例偏向上。 这是一个与时间有关的问题,这是值得怀疑的。
只需使用Ticks,使用Ticks来分割,平铺/整理/舍入数值,然后再乘以。
如果你只是想把小时上限值整理一下
Console.WriteLine(DateTime.Now.ToString("M/d/yyyy hh:00:00"));