C# 如何将日期时间舍入到最接近的200毫秒?

C# 如何将日期时间舍入到最接近的200毫秒?,c#,.net,C#,.net,在我正在编写的一个C#Net应用程序中,我希望将一些日期时间值舍入到最接近的200毫秒。我已经想出了以下代码 public static DateTime RoundToTheTwoHundredthMillisecond(DateTime dt) { var ms = dt.Millisecond; var s = dt.Second; var m = dt.Minute; var h = dt.Ho

在我正在编写的一个C#Net应用程序中,我希望将一些日期时间值舍入到最接近的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, m, h, s, 0, dt.Kind).AddSeconds(1);
        } 
        else {
            return new DateTime(y, M, d, m, h, s, ms, dt.Kind);
        }                     
    }
public static DateTime roundtothetwoundredthmillissecond(DateTime dt){
var ms=dt.毫秒;
var s=第二个;
var m=dt.分钟;
var h=dt.小时;
var d=日;
var M=月的dt;
变量y=dt.年;
如果(ms>=900&&ms<1000)ms=1000;
如果(ms>=700&&ms<900)ms=800;
如果(ms>=500&&ms<700)ms=600;
如果(ms>=300&&ms<500)ms=400;
如果(ms>=100&&ms<300)ms=200;
如果(ms>=0&&ms<100)ms=0;
//1000是无效的毫秒。我们需要舍入一秒。使用AddSeconds,以便在距离新分钟1秒、距离新小时1分钟时自动上卷…等等…闰年和闰月也被处理。。。。
如果(ms==1000){
返回新的日期时间(y,M,d,M,h,s,0,dt.Kind);
} 
否则{
返回新的日期时间(y,M,d,M,h,s,ms,dt.Kind);
}                     
}

我认为这可能是有效的。但我想知道是否有人能给我指出一种比我的摸索更可靠的方法?或者,也许,这是一个可以/应该为之编写单元测试的东西吗?(这样做似乎也容易让我犯错误)

你可以用200除法,四舍五入,然后再相乘得到值。另外,您只需从原始的
DateTime
中减去差异,无需重建它的组件my component

public static DateTime RoundToTheTwoHundredthMillisecond(DateTime dt)
{
    var ms = Math.Round(dt.Millisecond / 200.0) * 200;
    return dt.AddMilliseconds(ms- dt.Millisecond);
}
编辑

为了模拟精确的
if
序列,我们可以使用
middpointrounding

public static DateTime RoundToTheTwoHundredthMillisecond(DateTime dt)
{
    var ms = Math.Round(dt.Millisecond / 200.0, MidpointRounding.ToEven) * 200;
    return dt.AddMilliseconds(ms- dt.Millisecond);
}

您可以使用此表达式(有错误)

更新: 正确的代码,括号少;)


ms
除以
200
,然后四舍五入,再乘以200就足够了,例如
Math.round(ms/200)*200
。我不是
.net
用户,但假设DateTime对象具有方法
addMissicles
,您就不能这样做:
返回dt.addMissicles(200-dt.ms%200)
?我想你需要使用
中点舍入。远离零
,以符合OPs的期望。@Evk-hm,你是对的,这不仅仅是直接向上舍入到最近的
200
,我“尝试复制行为,并在一秒钟内进行编辑。这是一个指向中点舍入的链接(对于那些不知道它是什么的人,即我来说)好答案。就像上面的泰坦。对我来说,你们比我聪明多了!
var value = DateTime.Now;
var roundedValue = DateTime.MinValue + TimeSpan.FromMilliseconds(((((long)((value - DateTime.MinValue).TotalMilliseconds) + 199) / 200) * 200)));
class Program
{
    static void Main(string[] args)
    {
        for (int index = 0; index < 20; ++index)
        {
            System.Threading.Thread.Sleep(349);
            DateTime value = DateTime.Now;
            DateTime rounded = value.RoundTo200thMillisecond();
            Console.WriteLine($"value = {value:yyyy-MM-dd HH:mm:ss.fff}, rounded = {rounded:yyyy-MM-dd HH:mm:ss.fff}");
        }
    }
}

public static class DateTimeExtensions
{
    public static DateTime RoundTo200thMillisecond(this DateTime value)
    {
        long elapsed = (long)((value - DateTime.MinValue).TotalMilliseconds);
        return DateTime.MinValue + TimeSpan.FromMilliseconds((elapsed + 100) / 200 * 200);
    }
}
value = 2018-05-22 21:50:38.174, rounded = 2018-05-22 21:50:38.200
value = 2018-05-22 21:50:38.534, rounded = 2018-05-22 21:50:38.600
value = 2018-05-22 21:50:38.893, rounded = 2018-05-22 21:50:38.800
value = 2018-05-22 21:50:39.252, rounded = 2018-05-22 21:50:39.200
value = 2018-05-22 21:50:39.612, rounded = 2018-05-22 21:50:39.600
value = 2018-05-22 21:50:39.971, rounded = 2018-05-22 21:50:40.000
value = 2018-05-22 21:50:40.330, rounded = 2018-05-22 21:50:40.400
value = 2018-05-22 21:50:40.690, rounded = 2018-05-22 21:50:40.600
value = 2018-05-22 21:50:41.049, rounded = 2018-05-22 21:50:41.000
value = 2018-05-22 21:50:41.409, rounded = 2018-05-22 21:50:41.400
value = 2018-05-22 21:50:41.768, rounded = 2018-05-22 21:50:41.800
value = 2018-05-22 21:50:42.127, rounded = 2018-05-22 21:50:42.200
value = 2018-05-22 21:50:42.487, rounded = 2018-05-22 21:50:42.400
value = 2018-05-22 21:50:42.846, rounded = 2018-05-22 21:50:42.800
value = 2018-05-22 21:50:43.206, rounded = 2018-05-22 21:50:43.200
value = 2018-05-22 21:50:43.565, rounded = 2018-05-22 21:50:43.600
value = 2018-05-22 21:50:43.924, rounded = 2018-05-22 21:50:44.000
value = 2018-05-22 21:50:44.284, rounded = 2018-05-22 21:50:44.200
value = 2018-05-22 21:50:44.643, rounded = 2018-05-22 21:50:44.600
value = 2018-05-22 21:50:45.002, rounded = 2018-05-22 21:50:45.000