.NET TimeSpan类计算TotalMilliseconds是否存在Bug?
问题:DateTime与DateTimeOffset计算Unix纪元毫秒数结果不一致
执行以下PowerShell脚本:
$> ([DateTime]"2023-10-16T16:56:14.052Z" - [DateTime]"1970-01-01T00:00:00.000Z").TotalMilliseconds
得到结果:
1697478974052
但使用DateTimeOffset执行:
$> ([DateTimeOffset]"2023-10-16T16:56:14.052Z").ToUnixTimeMilliseconds()
得到的结果相差3600000毫秒(1小时),且后者是正确的Unix纪元毫秒数:
1697475374052
为什么两个命令结果不一致?
原因分析
核心问题出在DateTime的Kind属性:
- 带
Z(UTC标识)的字符串转换为DateTime对象时,PowerShell默认不会将其识别为UTC时间,而是标记为Unspecified类型(既非UTC也非本地时间)。 - 计算两个
Unspecified类型的DateTime差值时,系统会隐式将它们当作本地时区时间处理。如果你的本地时区是UTC+1(如欧洲中部时间),就会导致计算结果比实际UTC时间的差值多1小时。 DateTimeOffset会正确解析字符串中的Z标识,将其视为UTC偏移量(偏移量0),调用ToUnixTimeMilliseconds()时直接基于UTC时间计算,结果自然正确。
解决方法
将DateTime明确标记为UTC类型后再计算:
# 方法1:转换为UTC时间 $utcDate = ([DateTime]"2023-10-16T16:56:14.052Z").ToUniversalTime() $epoch = ([DateTime]"1970-01-01T00:00:00.000Z").ToUniversalTime() ($utcDate - $epoch).TotalMilliseconds # 方法2:指定Kind为UTC $utcDate = [DateTime]::SpecifyKind([DateTime]"2023-10-16T16:56:14.052Z", [DateTimeKind]::Utc) $epoch = [DateTime]::SpecifyKind([DateTime]"1970-01-01T00:00:00.000Z", [DateTimeKind]::Utc) ($utcDate - $epoch).TotalMilliseconds
两种方法得到的结果都会和DateTimeOffset的输出一致:1697475374052
内容的提问来源于stack exchange,提问作者jad45
相关产品推荐
相关产品推荐

