我发现DateTime转换为long,反之亦然。在测试转换后,我发现它们有时会提供与原始时间相差一秒的结果。 这是一个最小的,完整的,可验证的例子
public static class DateTimeConstants
{
public static readonly DateTime ZeroTime =
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
}
public static class DateTimeExtensions
{
public static long ToLong(this DateTime value)
{
return Convert.ToInt64((value.ToUniversalTime() -
ZeroTime).TotalSeconds)
}
}
public static class LongExtensions
{
public static DateTime ToDateTime(this long value)
{
var dateTime = ZeroTime.AddSeconds(value);
return dateTime.ToLocalTime();
}
}
public void ConvertDateTimeToLongAndBackTest()
{
var initialDateTime = DateTime.Now;
var longDateTime = initialDateTime.ToLong();
var result = longDateTime.ToDateTime();
Assert.AreEqual(result.Date, initialDateTime.Date);
Assert.AreEqual(result.Hour, initialDateTime.Hour);
Assert.AreEqual(result.Minute, initialDateTime.Minute);
// Fails on the following line sometimes
Assert.AreEqual(result.Second, initialDateTime.Second);
}
有时,生成的DateTime与我为测试实例化的原始DateTime相同,但有时它会关闭一秒钟。这是为什么?
答案 0 :(得分:6)
好吧,既然你要缩短秒数,很明显你可能会失去一秒精度。例如。 12.8 seconds
可能会打印为13
并进行舍入,但您的算法会将其转换为12
。如果你不一致地使用相同的舍入,即使进行舍入也可能会遇到麻烦。
编辑:既然您已经实际添加了代码,我可以更具体一点 - DateTime.Second
截断当前秒,而Convert.ToInt64
则将其舍入。所以12.8秒,你将获得第二个13而不是原来的12.修复很简单 - 用简单的强制转换替换转换。或者,如果您无法更改格式(即某人已经依赖于错误行为),请在日期时间内将测试更改为向上秒。
如果您想要unix时间,请使用unix时间。如果要使用二进制格式进行持久化,请使用ToBinary
。不要试图制作自己的日期时间格式,日期不是简单的。
答案 1 :(得分:1)
DateTime
具有精确到小到一秒的精度。 TotalSeconds
函数可能在每次调用时向上或向下舍入。这将解释您在转换数字时有时会看到的差异。
每当数字向上舍入时,它会为结果增加一秒。