C# 日期时间向上和向下舍入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11364481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
DateTime Round Up and Down
提问by parliament
Ive been looking for a proper rounding mechanism but nothing I find seems to be exactly what I need.
我一直在寻找一种合适的舍入机制,但我发现没有什么似乎正是我需要的。
I need to round up and round down seperately and I also need to account for the the case when its already rounded.
我需要分别向上舍入和向下舍入,并且我还需要考虑已经舍入的情况。
I need the following rounding to happen
我需要进行以下四舍五入
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
Basically I need it to RoundUp() or RoundDown() to the nearest 10 minutes explicitly but it should also leave time untouched if it already is in a multiple of 10 minutes. Also I'd like to truncate any seconds to that they have no effect on the rounding procedure
基本上,我需要将其显式地设置为 RoundUp() 或 RoundDown() 到最近的 10 分钟,但如果它已经是 10 分钟的倍数,它也应该保持时间不变。此外,我想截断任何秒数,以确保它们对舍入过程没有影响
4:50:45 -> 4:50:00 -> RoundUp() -> 4:50
4:50:45 -> 4:50:00 -> RoundUp() -> 4:50
Does anyone have any handy code to accomplish this.
有没有人有任何方便的代码来实现这一点。
I found this code somewhere but it rounds 5:00 -> RoundUp() -> 5:10 rather than leaving it intact because its already a multiple of 10 and needs no rounding. Also Im not sure how seconds would effect it
我在某处找到了这段代码,但它四舍五入 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));
}
Hope someone can edit that method to make it work for me. Thanks
希望有人可以编辑该方法以使其对我有用。谢谢
采纳答案by mellamokb
How about:
怎么样:
case RoundingDirection.Up:
t = dt.AddMinutes((60 - dt.Minute) % 10);
case RoundingDirection.Down:
t = dt.AddMinutes(-dt.Minute % 10);
Demo: http://ideone.com/AlB7Q
回答by aj.toulan
This will let you round according to any interval given.
这将让您根据给定的任何间隔进行舍入。
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));
}
}
To take care of truncating the seconds, I would simply subtract the seconds and milliseconds from the date-time before sending them into the rounding functions.
为了处理截断秒数,我会在将它们发送到舍入函数之前简单地从日期时间中减去秒数和毫秒数。
回答by JasonS
Here is a fast way to truncate (round down)
这是截断(向下舍入)的快速方法
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)));
回答by Keith Gresham
This function will round up or down to the nearest interval (minutes).
此函数将向上或向下舍入到最接近的间隔(分钟)。
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);
}
回答by Kevin Swann
Another approach avoiding arithmetic using type long.
使用 type 避免算术的另一种方法long。
Using integer division, where a & b are positive integers:
使用整数除法,其中 a & b 是正整数:
a/b // rounding down
(a+b-1)/b // rounding up
((2*a)+b)/(2*b) // rounding to the nearest (0.5 up)
To round 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 );
}
To round down or to nearest, change the mins calculation as appropriate.
要四舍五入或最接近,请根据需要更改分钟计算。
The minutes are rounded. The seconds & milliseconds are zeroed which is expected behaviour.
分钟是四舍五入的。秒和毫秒归零,这是预期的行为。

