C# DateTime.ToString的格式“o”在Azure上返回不同的字符串

6

我有一个场景,需要将UTC日期转换为带有特定时区的ISO 8601字符串,以通过Web API发送。推荐的方法是使用TimeZoneInfo进行如下操作:

var configuredTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneString);
var localTime = DateTime.SpecifyKind(TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone), DateTimeKind.Local);
var stringResult = localTime.ToString("o");

这在我的本地机器上很好用,但是当代码托管到 Azure Web 应用程序时,我遇到了一个非常奇怪的情况,即 ToString 输出的字符串与本地不同。本地输出的是 2017-02-20T00:00:00-06:00(这正是我想要的,因为它包含我需要的时区信息),但是在 Azure 中托管时,我得到的是 2017-02-20T00:00:00+00:00(这是 UTC,不是我想要的)。由于我正在手动应用所需的时区,因此我不确定为什么格式会附加错误的时区信息。是否有人遇到过类似的问题?

DateTime 无法存储时区。 - SLaks
4
在Azure中,本地时区是UTC。 - Mickaël Derriey
我通过 TimeZoneInfo.ConvertTimeFromUtc 手动提供所需的时区,那么 Azure 使用 UTC 会如何影响转换? - Nathan G
1个回答

7
正如评论中提到的那样,System.DateTime无法存储时区信息。它只知道“本地”或者“UTC”。由于Azure托管,它的“本地”时间就是UTC。
因此,你的语句TimeZoneInfo.ConvertTimeFromUtc(utcTime, configuredTimeZone)将把UTC时间转换为你的时间(20日午夜),但是由于DateTime不包含时区信息,它的值为DateTimeKind.Unspecified。而DateTime.SpecifyKind(..., DateTimeKind.Local)则告诉它的类型是“本地”时间,在Azure主机上是UTC+00:00。
如果时区很重要,你应该使用System.DateTimeOffset,而不是DateTime。它专门用于保存和操作时区偏移量。

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