C#如何转换Unix时间并解决1天丢失的问题

4

以下是代码:

var date = DateTime.Now.Date;
var ms = (long)(date - DateTimeOffset.UnixEpoch).TotalMilliseconds;
var date1 = DateTimeOffset.FromUnixTimeMilliseconds(ms).DateTime.Date;

date是24号,而date1是23号

为什么它们不匹配?


4
很可能是时区的问题。DateTime.Now 是以您的本地时区为基础的。DateTimeOffset.UnixEpoch 是以 UTC 为基础的。执行 date - DateTimeOffset.UnixEpoch 将进行时区转换,因此 ms 给出了自 UNIX 纪元(UTC)到您本地时区的“现在”之间的秒数。目前为止都很好。 DateTimeOffset.FromUnixTimeMilliseconds(ms) 会给您提供一个以 UTC 为基础的 DateTimeOffset,所以 date1 将是以 UTC 而不是您的本地时区为基础的。由此可知,您必须比 UTC 时间提前? - canton7
1个回答

6

使用 DateTimeOffset.FromUnixTimeMilliseconds(ms).LocalDateTime

DateTime.NowKind = Local,所以它会偏移您的UTC偏移量。

您可以通过以下方式查看:

var kind = DateTime.Now.Date.Kind;

然后您可以使用“kind”进行小型测试:

var date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local);
var ms = (long)(date - DateTimeOffset.UnixEpoch).TotalMilliseconds;

ms是多少?根据冬夏令时和您所在的位置,它可能不是0。

因此,您的ms包括您的UTC偏移量。现在您需要:

var date1 = DateTimeOffset.FromUnixTimeMilliseconds(ms).LocalDateTime;

希望您仍然处于"原始" UTC 偏移量中(因此在计算datedate1之间的天数不足以使您在冬令时/夏令时之间切换)。
(如果您正确地完成了所有操作,实际上不需要在.LocalDateTime之后加上.Date,因为日期应该已经是00:00:00)。

你说的没错,它可以工作。但我不明白为什么。我与UTC只相差2小时。 - Boppity Bop
4
@BoppityBop 这两个小时将00:00时间推到前一天的22:00时间。在C#中没有“纯日期”类型。使用.Date可以将时间设置为00:00。 - xanatos
2
@BoppityBop 没错。别忘了你正在使用 DateTime.Now.Date -- .Date 很重要,因为它给你一个代表当天午夜的 DateTime - canton7
3
作为一种抱怨,DateTime中的Kind信息是.NET 1.0中最糟糕的想法之一,但不幸的是我们必须继续使用它。我只看到它会导致问题,并且从未见过它有任何用处。 - xanatos
同意。在可能的情况下使用 DateTimeOffset(只有极少数情况不适用),对于那些 DateTimeOffset 无法胜任的情况,考虑使用类似 NodaTime 的东西。 - canton7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接