我有一个简单的 DateTime 对象,等于日期:
11/1/2020 8:11:14 AM
。
我想将其转换为毫秒,所以我这样做:
myTimestamp?.Ticks / TimeSpan.TicksPerMillisecond
。
我得到了
63739786274788
,从纯粹的计算角度来看这似乎是正确的。
但是,当我将其输入其中一个在线转换器进行验证时,我得到了日期
Wed Nov 01 3989 01:11:14
,这当然是错误的。
问题:
63739786274788
如果不是以毫秒为单位的时间?在 .NET 中,
DateTime
刻度基于 0001-01-01T00:00:00.0000000
纪元。 .Kind
属性用于决定是 UTC、本地时间还是“未指定”。
大多数在线转换器(例如您链接的转换器)都期待一个 Unix Timestamp,其中该值基于
1970-01-01T00:00:00.000Z
纪元。它始终基于 UTC。 (精度不一,常用秒和毫秒。)
如果您想从 .NET 获取基于毫秒的 Unix 时间戳,您应该使用内置函数
DateTimeOffset.FromUnixTimeMilliseconds
和 DateTimeOffset.ToUnixTimeMilliseconds
,而不是除法。 (这些函数还有基于秒的版本。)
假设您的输入值基于 UTC:
DateTime dt = new DateTime(2020, 11, 1, 8, 11, 14, DateTimeKind.Utc);
DateTimeOffset dto = new DateTimeOffset(dt);
long timestamp = dto.ToUnixTimeMilliseconds();
// output: 1604218274000
DateTimeKind.Local
也适用于此,假设您的值确实基于计算机的本地时区。 DateTimeKind.Unspecified
有点棘手,因为您需要首先使用 DateTimeOffset
转换为具有特定时区的 TimeZoneInfo
。
您还可以直接构造
DateTimeOffset
值,而不是完全通过 DateTime
。
好的,那么您首先将 Ticks 除以 System.TimeSpan.TicksPerMillisecond (10,000)
如您所见,您生成的数字远大于当前的毫秒数:
63739786274788
1607363529803
简短的回答是,Ticks 是基于 0001 年 1 月 1 日午夜 12:00:00,而你的在线计算器是基于 Unix 时间,1970 年 1 月 1 日。所以这可以解释为什么你的时间差了大约 2,000 年。如果您从新的 DateTime(1970,1,1) 中减去刻度,那么这将为您提供满足在线计算器的正确数字。
有关更多信息,我建议阅读 MS 关于 DateTime 的文档