我想将Gusman's 和Evan's cmets 结合起来,如果他们允许的话,我会提出一些反对他们的论据。让我们一步一步来..
DateTime.UtcNow 应该有一个时区偏移量吗?
无论Kind 有什么(本地、UTC 或未指定),DateTime 实例都不会保留任何 UTC 偏移值。期间。
首先我们看一下The "zzz" format specifier的文档;
对于 DateTime 值,“zzz”自定义格式说明符表示
本地操作系统时区与 UTC 的带符号偏移量,
以小时和分钟为单位。 它不反映一个人的价值
实例的 DateTime.Kind 属性。因此,“zzz”格式
说明符不推荐用于 DateTime 值。
根据前两个粗体句子,LINQPad 生成的两个结果都完全符合预期。您可以在 Visual Studio 中获得相同的结果(当然是日期和时间部分)。
只需将此代码运行为“不调试就启动”(Ctrl + F5)
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
但是,当您使用 (F5) 将其作为“开始调试”运行时呢?
在这种情况下有两个选项取决于您在Managed Debugging Assistants 中的DateTimeInvalidLocalFormat 是否打勾。此部分在Debug 菜单上,然后单击Exceptions。
如果勾选了这个选项,你会得到一个异常,它会说:
A UTC DateTime 被转换为文本格式,仅
正确的当地时间。调用时可能会发生这种情况
DateTime.ToString 使用 'z' 格式说明符,其中将包括
输出中的本地时区偏移量。在这种情况下,要么使用'Z'
格式说明符,指定 UTC 时间,或使用 'o' 格式
字符串,这是在文本中保存 DateTime 的推荐方式。
如果不勾选此选项,您将不会收到任何消息,结果将与 LINQPad 相同。
鉴于第二个结果是世界时,我预计它会返回
2016-01-08T16:05:04-00:00(时区偏移为零)。
正如我所解释的,zzz 格式说明符 not 的行为类似于 any DateTime 实例。
但对于记录为的DateTimeOffset 实例,它的行为不同;
对于DateTimeOffset 值,此格式说明符表示
DateTimeOffset 值的 Offset 以小时为单位,UTC 时间。
并且DateTimeOffset.Now 和DateTimeOffset.UtcNow 完全符合您的期望,无论您在 LINQPad 或 Visual Studio 中运行,因为它们被记录为;
现在
一个 DateTimeOffset 对象,其日期和时间是当前本地时间
并且其偏移量是本地时区相对于 Coordinated 的偏移量
世界标准时间 (UTC)。
UtcNow
一个对象,其日期和时间是当前的 Coordinated Universal
时间 (UTC) 和 其偏移量是 TimeSpan.Zero。
Console.WriteLine(DateTimeOffset.Now.ToString("yyyy-MM-ddTHH:mm:sszzz"));
Console.WriteLine(DateTimeOffset.UtcNow.ToString("yyyy-MM-ddTHH:mm:sszzz"));
会生成
2016-01-08T09:05:04-07:00
2016-01-08T16:05:04-00:00
Tl;dr 我认为这不是一个错误。 LINQPad 生成正确的结果正是它应该是什么。在 Visual Studio 中,如果 that 选项被勾选或未处于调试模式,您可能会遇到异常。