C#DateTime将长时间转换为1秒

时间:2016-12-09 14:58:46

标签: c# datetime

我发现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相同,但有时它会关闭一秒钟。这是为什么?

2 个答案:

答案 0 :(得分:6)

好吧,既然你要缩短秒数,很明显你可能会失去一秒精度。例如。 12.8 seconds可能会打印为13并进行舍入,但您的算法会将其转换为12。如果你不一致地使用相同的舍入,即使进行舍入也可能会遇到麻烦。

编辑:既然您已经实际添加了代码,我可以更具体一点 - DateTime.Second截断当前秒,而Convert.ToInt64则将其舍入。所以12.8秒,你将获得第二个13而不是原来的12.修复很简单 - 用简单的强制转换替换转换。或者,如果您无法更改格式(即某人已经依赖于错误行为),请在日期时间内将测试更改为向上秒。

如果您想要unix时间,请使用unix时间。如果要使用二进制格式进行持久化,请使用ToBinary。不要试图制作自己的日期时间格式,日期不是简单的。

答案 1 :(得分:1)

DateTime具有精确到小到一秒的精度。 TotalSeconds函数可能在每次调用时向上或向下舍入。这将解释您在转换数字时有时会看到的差异。

每当数字向上舍入时,它会为结果增加一秒。