C#日期时间.带有zzz的ToString在dotnet框架中中断,但在dotnet核心中不中断



我的本地时间是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-ddTHH:mm:sszzz"));
Assert.AreEqual(DateTimeKind.Local, myLocalDate.Kind);
Assert.AreEqual(myLocalDate, myLocalDate.ToLocalTime());

现在,我在utc中通过手动减去一个小时并指定"0"来创建相同的时间;utc";同样善良。但当我调用ToString时,时区写为+01:00,我希望它是+00:0:

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-ddTHH:mm:sszzz"));

错误消息:

消息:明确肯定AreEqual失败。应为:<2020-11-25T07:0:00+00:00>。实际:<2020-11-25T07:00+01:00>。

我是错过了这里的日期时间和格式,还是这可能是一个已知的错误?

我跑了。Net Framework 4.8

这篇文章是关于同样的问题,我看到:如何解决DateTimeInvalidLocalFormat错误:;UTC DateTime正在转换为仅适用于本地时间的文本格式"?

更新:

运行以下程序会在dotnet框架和dotnet核心中产生不同的结果(如evk所述(:

Console.WriteLine(new DateTime(2025, 11, 25, 07, 00, 00, DateTimeKind.Utc).ToString(@"yyyy-MM-ddTHH:mm:sszzz"));

dotnet核心打印:

2020-11-25T07:00:00:00+00:00

dotnet框架打印:

2020-11-25T07:00+01:00

此外,在调试模式下运行dotnet框架时,会显示以下调试助手消息,但在DateTime内部会被忽略。ToString((:

托管调试助手"DateTimeInvalidLocalFormat":"正在将UTC DateTime转换为仅适用于本地时间的文本格式。调用DateTime时可能会发生这种情况。使用"z"格式说明符的ToString,该格式说明符将在输出中包括本地时区偏移量。在这种情况下,可以使用指定UTC时间的"Z"格式说明符,也可以使用"o"格式字符串,这是将DateTime持久化为文本的建议方式。当传递要由XmlConvert或DataSet序列化的DateTime时,也可能发生这种情况。如果使用XmlConvert。ToString,传入XmlDateTimeSerializationMode。RoundtripKind无法正确序列化。如果使用DataSet,请将DataColumn对象的DateTimeMode设置为DataSetDateTime。Utc.'

不,它的行为与文档一样。来自zzz格式说明符(强调矿(的文档:

对于DateTime值;zzz";自定义格式说明符表示本地操作系统时区与UTC的带符号偏移量,以小时和分钟为单位它不反映实例的DateTime.Kind属性的值。由于这个原因;zzz";不建议将格式说明符与DateTime值一起使用。

可以说这很不幸,但这不是一个bug。

请注意。NET Core(和.NET 5.0(显然的行为并不像文档中所描述的那样。虽然你可能会争辩说;固定的";在里面NET核心,我认为以未记录的方式行为本身就是一个错误,可能会使代码迁移比预期的更困难。

我建议您遵循文档中的建议,避免使用zzzDateTime值。我建议使用我的Noda Time库,其中没有值"的模糊性;可能是本地的或者可能是UTC";,但这是一个稍微不同的问题。(我不希望你在使用Noda Time时遇到这个问题,希望你的其他日期/时间代码会更清晰。(

最新更新