You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#.Net中将DateTime值四舍五入到最近的200毫秒?

问题:将DateTime四舍五入到最近的200毫秒

我正在开发一个C#.Net应用,需要将部分DateTime值四舍五入到最近的200毫秒。我已编写如下代码:

public static DateTime RoundToTheTwoHundredthMillisecond(DateTime dt) 
{ 
    var ms = dt.Millisecond; 
    var s = dt.Second; 
    var m = dt.Minute; 
    var h = dt.Hour; 
    var d = dt.Day; 
    var M = dt.Month; 
    var y = dt.Year; 

    if (ms >= 900 && ms < 1000) ms = 1000; 
    if (ms >= 700 && ms < 900) ms = 800; 
    if (ms >= 500 && ms < 700) ms = 600; 
    if (ms >= 300 && ms < 500) ms = 400; 
    if (ms >= 100 && ms < 300) ms = 200; 
    if (ms >= 0 && ms < 100) ms = 0; 

    // 1000 is an invalid millisecond. We need to round up a second. Use AddSeconds so it will automatically roll up should we be 1 second away from a new minute, 1 minute away from a new hour...etc...leap years and months are handled also.... 
    if (ms == 1000) { 
        return new DateTime(y, M, d, h, m, s, 0, dt.Kind).AddSeconds(1); 
    } else { 
        return new DateTime(y, M, d, h, m, s, ms, dt.Kind); 
    } 
}

我认为这段代码可能可行,但想请教是否有更可靠的实现方法?另外,是否需要为此编写单元测试?(担心测试编写也会出现疏漏)


优化实现方案

你的代码逻辑是没问题的,但多个if判断显得有些繁琐,而且可以通过数学计算来简化逻辑,同时保证可靠性。核心思路是把时间转换为当天的总毫秒数,对200毫秒的间隔做四舍五入,再转换回DateTime——利用DateTime的内置方法自动处理进位(跨秒、跨分钟甚至跨年都不用手动管),代码更简洁也更不容易出错:

public static DateTime RoundToNearest200Ms(DateTime dt)
{
    // 计算从当天零点到当前时间的总毫秒数
    long totalMilliseconds = (long)(dt - dt.Date).TotalMilliseconds;
    // 四舍五入到最近的200毫秒间隔
    long roundedMs = (long)Math.Round(totalMilliseconds / 200.0) * 200;
    // 重新构建DateTime,保留原有的Kind信息
    return dt.Date.AddMilliseconds(roundedMs).SpecifyKind(dt.Kind);
}

为什么这个方案更可靠?

  • 避免了手动枚举毫秒区间的if判断,减少了逻辑疏漏的可能
  • Math.Round会自动处理四舍五入规则,比如900毫秒会被计算为1000毫秒(即1秒),AddMilliseconds会自动把这1000毫秒转换为1秒,跨秒、跨分钟这类场景(比如59秒950毫秒进位到下一分钟0秒0毫秒)也能自动处理
  • 完整保留了原DateTime的Kind属性,避免时区相关的问题

关于单元测试:非常有必要!

时间处理的边界情况特别多,很容易踩坑,所以单元测试是必须的。你可以针对以下关键场景编写测试用例:

  • 基础边界值:
    • 输入00:00:00.099 → 应该返回00:00:00.000
    • 输入00:00:00.100 → 应该返回00:00:00.200
    • 输入00:00:00.899 → 应该返回00:00:00.800
    • 输入00:00:00.900 → 应该返回00:00:01.000
  • 跨时间单位场景:
    • 输入00:00:59.950 → 应该返回00:01:00.000
    • 输入23:59:59.950 → 应该返回次日的00:00:00.000
  • DateTime.Kind测试:
    • 测试Utc、Local、Unspecified三种Kind的输入,确保输出的Kind和输入一致
  • 刚好命中200毫秒间隔的情况:
    • 输入00:00:00.200 → 返回自身,验证不会被错误修改

这些测试用例可以覆盖大部分容易出错的场景,确保你的方法在各种情况下都能正确工作。

内容的提问来源于stack exchange,提问作者Obbles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:30:09