C# Epoch 日期时间转换

Posted

技术标签:

【中文标题】C# Epoch 日期时间转换【英文标题】:C# Epoch DateTime conversion 【发布时间】:2020-06-15 01:41:57 【问题描述】:

我需要在 c# 中处理纪元时间,为此我创建了以下两种扩展方法:

public static DateTime ToDateTime(this double epochTime)

    return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(epochTime);


public static double ToEpochTime(this DateTime dt)

    var t = dt - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
    return t.TotalSeconds;

运行以下测试时失败:

[Fact]
public void Test_EpochTime()

    var dateToTest = DateTime.Now;

    var epoch = dateToTest.ToEpochTime();
    var result = epoch.ToDateTime();

    Assert.Equal(result, dateToTest);

结果是:

Xunit.Sdk.EqualException: 'Assert.Equal() 失败

预计:2020-03-02T17:43:19.1830000Z

实际:2020-03-02T17:43:19.1831870+00:00'

以前有没有人遇到过这种情况,在 double/DateTime 之间转换有问题吗?

提前感谢您的任何指点!

【问题讨论】:

好奇,你用的是小数秒吗?如果它们是整数,为什么不直接使用 long 而不是 double? 不要在单元测试中使用.Now。它会导致测试仅在特定时间(闰日、夏令时等)失败。 除非您的目标是 4.6 之前的 .NET Framework,否则正如 this answer 指出的那样,已经有内置方法。 您的预期值和实际值在 Assert 中是错误的。双精度只有足够的精度来保持毫秒。如果您想要更精确,则必须使用很长的Ticks。如果你想要毫秒,那么正如@Magnetron 指出的那样,有内置的方法。最重要的是,这是一般建议,如果您需要精确值,请不要使用 double 或 float 类型。 @iakobski - 就是这样! (请将此作为答案,以便我标记) 【参考方案1】:

双精度只有足够的精度来保持毫秒。如果您想要更精确,则必须使用很长的DateTime.Ticks。 long 是一个精确的值,它不会改变。

如果你想要毫秒,那么正如@Magnetron 指出的那样,有内置的方法。最重要的是,这是一般建议,如果您需要精确值,请不要使用 double 或 float 类型。

【讨论】:

【参考方案2】:

对我来说,解决方案是更改和使用 Ticks 以获得更高的精度(感谢 @iakobski)。以下是更新后的扩展方法:

public static DateTime ToDateTime(this long epochTime)

    return new DateTime(1970, 1, 1, 0, 0, 0).AddTicks(epochTime);


public static long ToEpochTime(this DateTime dt)

    var t = dt.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0);
    return t.Ticks;

【讨论】:

以上是关于C# Epoch 日期时间转换的主要内容,如果未能解决你的问题,请参考以下文章

在Android中将Epoch时间转换为日期并将日期转换为Epoch时间[重复]

将 Epoch 时间转换为日期

Epoch时间到日期和时间的全手动转换

如何在标准 SQL 中将 Epoch 时间戳转换为日期

将人类可读的日期从 Epoch 转换为变量

在linux中将特定日期格式转换为Epoch