.NET的DateTime.ToString("R")在使用UTC日期时是否存在Bug?

3

我是一名在英国的助手(目前处于GMT+1时区)。

如果我运行以下代码:

> DateTime.UtcNow.ToString("R")  // Or...
> DateTime.Now.ToUniversalTime().ToString("R")
"Mon, 06 Oct 2014 10:20:00 GMT"

正确答案。
如果我现在运行相同的代码,而没有进行UTC日期时间转换:

> DateTime.Now.ToString("R")
"Mon, 06 Oct 2014 11:20:00 GMT"

打印的时间是正确的,但时区不对。我期望的是:
"Mon, 06 Oct 2014 11:20:00"  // Or..
"Mon, 06 Oct 2014 11:20:00 BST"

问题: 这个行为是设计上的吗?我能否获得与“R”格式相同的输出,但带有正确的时区指示符?


"11:20 GMT" 不正确,假设你是在9分钟前做的。现在是11:20 BST,也就是10:20 GMT。第二个输出是正确的。 - Jon Skeet
@JonSkeet 是的,你是对的。问题应该反过来。正在纠正... - Mau
值得澄清的是,目前英国并不是你在问题中所说的GMT时区。英国有两个时区,GMT和BST。GMT与UTC相同,但在夏季,不能说英国的时区是GMT。 - Chris
@Mau:通过修正后的问题,显然问题在于微软编写时区代码的人似乎没有意识到我们对事物有不同的名称。我想知道美国人和其他有不同夏令时的人是否也有同样的问题,或者这只是英国独有的问题... - Chris
3
在大多数表示中,英国有一个时区(例如“欧洲/伦敦”),在一年中的不同时间观察到不同的UTC偏移和缩写。我不知道“半个时区”的好名称(例如BST),但我不会称它为时区。而且,我认为这并不是一个“事物不同名称”的问题 - 请参阅我的答案和文档。 - Jon Skeet
显示剩余2条评论
1个回答

7

这绝对不是错误,而是记录下来的行为:

自定义格式字符串为"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"。当使用此标准格式说明符时,格式化或解析操作始终使用不变的区域设置。

...

虽然RFC 1123标准将时间表示为协调世界时(UTC),但格式化操作不会修改正在被格式化的DateTime对象的值。因此,在执行格式化操作之前,必须通过调用DateTime.ToUniversalTime方法将DateTime值转换为UTC。相比之下,DateTimeOffset值会自动执行此转换;在执行格式化操作之前,无需调用DateTimeOffset.ToUniversalTime方法。

正如我在问题的评论中指出的那样,如果您在提问之前不久运行了代码,则10:20 GMT是正确的:11:20 GMT尚未发生。

基本上,当您按照文档中的指导调用ToUniversalTime时,它会执行正确的操作。如果不这样做,则会给出误导性的值-这很不幸,但在我看来是DateTime设计上的一部分问题。
您应该考虑至少使用DateTimeOffset,或者可能改用我的Noda Time项目。

1
谢谢。我们已经考虑了一段时间的Noda Time了 :) - Mau
@jon skeet 从我的角度来看,这似乎是一个错误... 这种行为有用例吗?还是仅仅因为有文档记录所以不被认为是一个错误? - marvc1
1
@marvc1:我无法对此发表评论。这将取决于您使用的“bug”定义。我希望至少现在不能更改,因为那可能会破坏功能。 - Jon Skeet
@JonSkeet 是的,我认为你说得对,这就是为什么它没有被更改的原因。我认为这只会“破坏”那些在调用.ToString("R")之前没有调用dateTime.ToUniversalTime()的人,像我们一样,已经有了一个错误,而实际上这个修改可以修复这个错误。如果我们一开始就使用Noda时间就好了... - marvc1
1
@marvc1:这取决于情况——如果您解析的内容已经在UTC中,但由于某种原因将其保留为“未指定”,那么调用ToUniversalTime()会破坏事情——但当前的行为是有效的。我可以看到这对某些人来说是适用的情况。 - Jon Skeet

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