JSON如何反序列化日期时间并将UTC转换为指定时区?

Posted

技术标签:

【中文标题】JSON如何反序列化日期时间并将UTC转换为指定时区?【英文标题】:How JSON deserialize datetime and convert from UTC to a specified time zone? 【发布时间】:2019-01-06 22:28:59 【问题描述】:

我想创建一个自定义的 json 序列化程序,它将带有 dateTime 的对象与 UTC 相互转换,并返回到指定的时区。 (非本地)

转换为 UTC 的示例是:

MyObject stuff = new MyObject();
stuff.Date = DateTime.Now;

string asdd = JsonConvert.SerializeObject(stuff,
            new JsonSerializerSettings()
            
                DateTimeZoneHandling = DateTimeZoneHandling.Utc
            );

如何通过 JsonSerializerSettings 或自定义序列化程序从 UTC 转换回特定时区?

注意:我正在使用 .NET Core 2.1。

【问题讨论】:

【参考方案1】:

时区转换不应在序列化或反序列化时处理。这些是单独的问题。

改为:

DateTimeZoneHandling 保留为默认RoundtripKind。 (不要设置为Utc。) 这具有以下行为:

如果您要反序列化为 DateTime,并且未在数据中传递任何偏移量,则将设置 DateTimeKind.Unspecified。 如果您要反序列化为 DateTime,并在数据中传递尾随 Z,则将设置 DateTimeKind.Utc。 如果您要反序列化为DateTime,并在数据中传递一个偏移量,则将设置`DateTimeKind.Local,并将值转换为本地时区(通常应该避免这种情况)。 如果您要反序列化为 DateTimeOffset,则偏移量将保持不变且值不会改变(如果传递偏移量,这是更好的方法)。

一旦您有了DateTimeDateTimeOffset 值,然后在必要时使用TimeZoneInfo.ConvertTime 和类似方法更改时区。这部分应该在您的应用程序代码中,因为它往往特定于特定 API 的逻辑。

一般来说,这是一种反模式 (SRP violation),它试图将所有传入或传出的日期/时间数据都放在同一时区,无论是通过序列化还是其他一些机制。

【讨论】:

以上是关于JSON如何反序列化日期时间并将UTC转换为指定时区?的主要内容,如果未能解决你的问题,请参考以下文章

当存储为 UTC 时,如何全局序列化和反序列化 Date 与 DateTime?

在反序列化期间将 JSON 日期转换为 .NET DateTime 的正确方法

SpringBoot中使用@RequestBody时如何自定义需要转换的日期格式

将 UTC 日期时间全局转换为用户指定的本地日期时间

C# JSON 将文件反序列化为对象列表失败,并将字符串转换为集合错误

Javascript将日期转换为UTC [重复]