【发布时间】:2022-01-19 15:40:19
【问题描述】:
我正在阅读 https://stackoverflow.com/a/6519330/1375882 并且我了解 DateTime 不包含时区。实际上,DateTime 没有 TimeZone 成员字段。然而有ToLocalTime() 和ToUniversalTime() 成员。例如。我正在 +2 时区计算机中测试我的代码,它给出了跟踪(例如,现在它在 +2 时区是16.12.2021 16:17:23)并且代码给出:
DateTime tmpNow = DateTime.UtcNow;
//16.12.2021 14:17:23 - this if fine, DateTime is UTC
tmp = tmpNow.ToString();
//16.12.2021 16:17:23
tmp = tmpNow.ToLocalTime().ToString();
//16.12.2021 14:17:23 - this is fine, DateTime is UTC
tmp = tmpNow.ToUniversalTime().ToString();
DateTime tmpCustom = new DateTime(2021, 12, 16, 16, 9, 10);
//16.12.2021 16:09:10 - this is strange, I assume that DateTime(...) is aware that it is
// executed in +2 and that 16:09:10 is in +2 and therefore ToString should be 14:09:10
tmp = tmpCustom.ToString();
//16.12.2021 18:09:10 - this is strange, see previous
tmp = tmpCustom.ToLocalTime().ToString();
//16.12.2021 14:09:10 - complete loss of understanding. If initialization has been to 14:09:10 UTC
// as I expected, then ToLocalTime.ToString had to bee 16:09:10, but ToLocalTime()... was 18:09:10
// hence ToUniversalTime() definitely had to be 2 hours before - 16:09:10.
tmp = tmpCustom.ToUniversalTime().ToString();
所以,这真的很奇怪 - DateTime 以某种方式感知它是使用 UTC 初始化还是使用简单的日期时间数字组合进行初始化。如何解释 DateTime 代码行为以及这种对隐藏时区的依赖?
【问题讨论】:
-
这是因为 tmpCustom 是“未指定”。如果您在未指定的情况下调用 ToLocal,C# 假定开发人员最了解您并且时间实际上是通用的,因此它会继续进行,就好像它是“UTC 到本地”并添加 2 小时。同样,如果它是未指定的并且您调用 ToUniversal,它会假设您知道它是本地的,并需要 2 小时才能使其成为通用。您调用的方法是指定源类型和目标;如果未指定,您可以想象这些方法称为“IsActuallyLocalMakeItToUniversal”和“IsActuallyUniversalMakeItToLocal”