为什么将DateTime格式化为字符串截断而不是以毫秒为单位?

时间:2011-09-14 13:24:52

标签: c# .net datetime rounding truncate

Double格式化为字符串时使用舍入。 E.g。

Console.WriteLine(12345.6.ToString("F0"));

输出

12346

但是,当DateTime被格式化为字符串时,会使用截断。 E.g。

var ci = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("2011-09-14T15:18:42.999", ci);
Console.WriteLine(dateTime.ToString("o", ci));
Console.WriteLine(dateTime.ToString("s", ci));
Console.WriteLine(dateTime.ToString("yyyy-MM-hhThh:mm:ss.f", ci));

输出

2011-09-14T15:18:42.9990000
2011-09-14T15:18:42
2011-09-14T15:18:42.9

这种行为背后的原因是什么(如果有的话)?


在格式化为字符串之前,可以通过添加半秒来实现舍入到最接近的秒:

var ci = CultureInfo.InvariantCulture;
var dateTime = DateTime.Parse("2010-12-31T23:59:59.999", ci);
Console.WriteLine(dateTime.ToString("s", ci));
var roundedDateTime = dateTime.AddMilliseconds(500);
Console.WriteLine(roundedDateTime.ToString("s", ci));

输出

2010-12-31T23:59:59
2011-01-01T00:00:00

2 个答案:

答案 0 :(得分:17)

这有点主观,但我会说舍入日期和时间值而不是截断它们会导致“更多”意外行为。

例如,舍入new DateTime(2011, 1, 1, 23, 59, 59, 999)将导致完全新的一天。这听起来比仅截断值更奇怪。

答案 1 :(得分:0)

在最后的测量单位,如果事件发生在该频率,则舍入会减少别名。

例如,如果抖动使得一秒钟的数据帧以2 mS进入第二帧,而下一帧以990 mS进入同一帧,则它们将被标记为在同一秒内。只有几毫秒的抖动会导致许多分散的非唯一键值。

圆形会让它们干净利落几秒钟 直到抖动变得更加严重,比如+/- 499 mS。

四舍五入的目的是阻止决议永远进行。 当不确定性低于分辨率时,它会极大地减少混叠。

“级联”只能在低于边界分辨率的情况下发生。 例如,一个切换年份数似乎令人震惊,但这只能发生在较少的情况下 从新年午夜开始,不到一秒钟(或毫秒等)。没什么意外的 或者特别不准确。

要真正防止别名(同时提到两次),您需要实现 四舍五入后的抗锯齿(如图中所示)。