我写作时使用的本地时间是GMT+01:00。当我按照以下方式进行ToString操作时,我经历了一些出乎意料的事情。来看看:
演示本地系统设置带有+01:00时区(所有这些都运行正常):
var myLocalDate = new DateTime(2020, 11, 25, 08, 00, 00, DateTimeKind.Local);
Assert.AreEqual("2020-11-25T08:00:00+01:00", myLocalDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
Assert.AreEqual(DateTimeKind.Local, myLocalDate.Kind);
Assert.AreEqual(myLocalDate, myLocalDate.ToLocalTime());
现在我手动减去一个小时并指定“utc”时区,创建了同样的时间(UTC时间)。 但是当我调用ToString时,时区被写成+01:00,我原本希望它是+00:00:
var myUtcDate = new DateTime(2020, 11, 25, 07, 00, 00, DateTimeKind.Utc);
// THIS Breaks:
Assert.AreEqual("2020-11-25T07:00:00+00:00", myUtcDate.ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
错误信息:
消息: Assert.AreEqual失败。 期望值:<2020-11-25T07:00:00+00:00>。 实际值:<2020-11-25T07:00:00+01:00>。
这里是关于日期时间和格式方面的疑问,还是说这可能是一个已知的 bug?
我正在运行 .Net Framework 4.8
这篇文章也是关于同样问题的:如何解决DateTimeInvalidLocalFormat错误:"正在将UTC DateTime转换为仅适用于本地时间的格式文本"?
更新:
按照以下程序运行会在dotnet framework和dotnet core中产生不同的结果(正如evk所提到的):
Console.WriteLine(new DateTime(2025, 11, 25, 07, 00, 00, DateTimeKind.Utc).ToString(@"yyyy-MM-dd\THH:mm:sszzz"));
dotnet core输出:
2020-11-25T07:00:00+00:00
dotnet Framework输出:
2020-11-25T07:00:00+01:00
此外,当以调试模式运行dotnet框架时,将显示以下调试助手消息,但在DateTime.ToString()内部被忽略:
“Managed Debugging Assistant 'DateTimeInvalidLocalFormat' : '正在将UTC DateTime转换为文本格式,该格式仅对本地时间正确。调用DateTime.ToString使用“z”格式说明符可能会发生这种情况,该说明符将在输出中包括本地时区偏移量。在这种情况下,请改用指定UTC时间的“Z”格式说明符或使用“o”格式字符串,这是建议的将DateTime持久化为文本的方法。当传递DateTime以由XmlConvert或DataSet序列化时,这也会发生。如果使用XmlConvert.ToString,请传递XmlDateTimeSerializationMode.RoundtripKind以正确序列化。如果使用DataSet,请在DataColumn对象上设置DateTimeMode为DataSetDateTime.Utc。“
zzz
作为格式说明符是有效的,正如您链接到的页面中所记录的那样。我不知道您在评论中想表达什么,但我认为它不清楚,不正确或两者都有。 - Jon Skeet