有没有更好的方法在C#中将DateTime四舍五入到最接近的5秒?

Dam*_*isa 18 c# algorithm performance datetime

我想将DateTime四舍五入到最接近的5秒.这是我目前正在做的方式,但我想知道是否有更好或更简洁的方式?

DateTime now = DateTime.Now;
int second = 0;

// round to nearest 5 second mark
if (now.Second % 5 > 2.5)
{
    // round up
    second = now.Second + (5 - (now.Second % 5));
}
else
{
    // round down
    second = now.Second - (now.Second % 5);
}

DateTime rounded = new DateTime(now.Year, now.Month, now.Day, now.Hour, now.Minute, second);
Run Code Online (Sandbox Code Playgroud)

请注意,我发现 2个前面的问题,但他们截断而不是的时间.

Mat*_*ler 46

(抱歉复活;我认识到这是一个陈旧且回答的问题 - 只是为了谷歌而添加了一些额外的代码.)

我从JayMcClellan的回答开始,但后来我希望它更通用,四舍五入到任意间隔(不仅仅是5秒).所以,我最终离开周杰伦的方法,一种使用Math.Round上的蜱虫,并把它转换成可以采取任意间隔的扩展方法,也提供改变舍入逻辑的选项(银行家舍入与外之零).我在这里张贴,以防这对其他人也有帮助:

    public static TimeSpan Round(this TimeSpan time, TimeSpan roundingInterval, MidpointRounding roundingType) {
        return new TimeSpan(
            Convert.ToInt64(Math.Round(
                time.Ticks / (decimal)roundingInterval.Ticks,
                roundingType
            )) * roundingInterval.Ticks
        );
    }

    public static TimeSpan Round(this TimeSpan time, TimeSpan roundingInterval) {
        return Round(time, roundingInterval, MidpointRounding.ToEven);
    }

    public static DateTime Round(this DateTime datetime, TimeSpan roundingInterval) {
        return new DateTime((datetime - DateTime.MinValue).Round(roundingInterval).Ticks);
    }
Run Code Online (Sandbox Code Playgroud)

它不会因为效率低而赢得任何奖项,但我发现它易于阅读且直观易用.用法示例:

new DateTime(2010, 11, 4, 10, 28, 27).Round(TimeSpan.FromMinutes(1)); // rounds to 2010.11.04 10:28:00
new DateTime(2010, 11, 4, 13, 28, 27).Round(TimeSpan.FromDays(1)); // rounds to 2010.11.05 00:00
new TimeSpan(0, 2, 26).Round(TimeSpan.FromSeconds(5)); // rounds to 00:02:25
new TimeSpan(3, 34, 0).Round(TimeSpan.FromMinutes(37); // rounds to 03:42:00...for all your round-to-37-minute needs
Run Code Online (Sandbox Code Playgroud)

  • 建议你在你创建的新`DateTime`上保持相同的`Kind`. (2认同)

Jay*_*lan 29

DateTime的Ticks计数表示100纳秒的间隔,因此您可以通过舍入到最近的50000000-tick间隔来舍入到最接近的5秒,如下所示:

  DateTime now = DateTime.Now;
  DateTime rounded = new DateTime(((now.Ticks + 25000000) / 50000000) * 50000000);
Run Code Online (Sandbox Code Playgroud)

这更简洁,但不一定更好.这取决于您是否更喜欢简洁和速度而不是代码清晰度.你的理解力更容易理解.

  • 这很好用,因为舍入到最接近的5的59秒将产生60,这不能作为'seconds'参数传递给DateTime构造函数.这样你就可以避免陷阱. (4认同)
  • 您可以使用TimeSpan.TicksPerSecond使其更具可读性. (2认同)