【发布时间】:2015-05-16 05:22:05
【问题描述】:
恐怕我不太了解 .Net 的 DateTime 类如何处理本地时间戳(我住在德国,所以我的语言环境是 de_DE)。也许有人可以启发我一点;-)
DateTime 构造函数可以用年、月等参数调用。此外,还可以提供 DateTimeKind 值 Local、Utc 或 Unspecified(=default)。
例子:
DateTime a = new DateTime(2015, 03, 29, 02, 30, 00, DateTimeKind.Local);
DateTime b = new DateTime(2015, 03, 29, 02, 30, 00, DateTimeKind.Utc);
DateTime c = new DateTime(2015, 03, 29, 02, 30, 00, DateTimeKind.Unspecified);
DateTime d = new DateTime(2015, 03, 29, 02, 30, 00);
根据定义,值 c 和 d 是相同的。但是,如果我将所有内容相互比较,所有四个都是相同的。在 VS 的调试器中检查对象显示Ticks 值(以及InternalTicks)对于所有对象都是相同的。但是,内部dateData 值不同,但显然被比较运算符忽略了。
您可能已经注意到,我为今年 3 月 29 日凌晨 02:30 构建了一个值。这个时间点在我们的时区中不存在,因为它通过切换到夏令时被跳过。所以我原以为构造对象a会得到一个异常,但这并没有发生。
此外,DateTime 有一个方法ToUniversalTime() 将解释为本地时间的值转换为等效的 UTC 值。为了测试,我运行了一个循环如下:
DateTime dt = new DateTime(2015, 03, 29, 01, 58, 00, DateTimeKind.Local);
DateTime dtEnd = new DateTime(2015, 03, 29, 03, 03, 00, DateTimeKind.Local);
while (dt < dtEnd)
{
Log(" Localtime " + dt + " converted to UTC is " + dt.ToUniversalTime());
dt = dt.AddMinutes(1);
}
结果是:
Localtime 29.03.2015 01:58:00 converted to UTC is 29.03.2015 00:58:00
Localtime 29.03.2015 01:59:00 converted to UTC is 29.03.2015 00:59:00
Localtime 29.03.2015 02:00:00 converted to UTC is 29.03.2015 01:00:00
Localtime 29.03.2015 02:01:00 converted to UTC is 29.03.2015 01:01:00
Localtime 29.03.2015 02:02:00 converted to UTC is 29.03.2015 01:02:00
...
Localtime 29.03.2015 02:58:00 converted to UTC is 29.03.2015 01:58:00
Localtime 29.03.2015 02:59:00 converted to UTC is 29.03.2015 01:59:00
Localtime 29.03.2015 03:00:00 converted to UTC is 29.03.2015 01:00:00
Localtime 29.03.2015 03:01:00 converted to UTC is 29.03.2015 01:01:00
Localtime 29.03.2015 03:02:00 converted to UTC is 29.03.2015 01:02:00
因此,.Net 将不存在的时间戳从本地时间转换为 UTC 没有问题。此外,向现有的本地时间戳添加一分钟不是本地感知的,并且会提供一个不存在的时间戳。
因此,添加 64 分钟后,转换后的 UTC 时间戳仅比之前大 4 分钟。
换句话说,本地时间和UTC之间的转换应该是一个双射,在合法的时间戳值之间给出一一对应的关系。
长话短说:我如何以预期的方式正确处理这个问题(根据.Net)?如果没有正确考虑,拥有DateTimeKind 是什么意思?我什至不敢问如何处理闰秒(23:59:60);-)
【问题讨论】:
-
这是 Jon Skeet 需要介入并使用 Noda Time 发表论文的地方
-
Hmya,你为什么要使用一个在实践中从未真正发生过的时间?你在锻炼GIGO,垃圾进垃圾出。不要惊讶你得到垃圾。如果您希望您的代码以可预测的方式运行,请严格使用 UTC,仅在可能的最后一刻转换为本地时间,就在人类看到它之前。
-
在相关的注释中,Jon 确实在那篇文章中提到闰秒的想法让他哭了。所以你并不孤单。 :)
-
@HansPassant:基础任务是针对一些基于时间的数据创建报告。我的基本方法是迭代民用(即本地)时间/日期,因为这决定了,例如,测量是否属于一个日期或另一个日期。按小时迭代时,会出现我发帖中显示的奇怪效果。目前这只是为了了解 DateTime API 是如何工作的。确实有效。不过我想我还是看看野田时间吧。
-
@paqogomez 取决于地球的哪个部分在给定时刻获得阳光,可能是 Jon Skeet 或 Matt Johnson,因为他们都是 NodaTime 的主要贡献者。
标签: c# .net datetime dst localtime