序列化时,Json.Net弄乱了DateTimeOffset的时区 [英] Json.Net messes up timezones for DateTimeOffset when serializing

查看:305
本文介绍了序列化时,Json.Net弄乱了DateTimeOffset的时区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了很多相关问题,但似乎没有一个对我有用.

I have looked at a lot of related questions but none of them seem to be working for me.

我正在尝试对UTC中的所有内容进行序列化.这是我的代码:

I'm trying to serialize everything in UTC. Here's my code:

class Class1
{
    static void Main()
    {
        Class2 foo = new Class2();
        JObject json = JObject.Parse(JsonConvert.SerializeObject(foo, new JsonSerializerSettings()
        {
            DateParseHandling = DateParseHandling.DateTimeOffset,
            DateFormatHandling = DateFormatHandling.IsoDateFormat,
            DateTimeZoneHandling = DateTimeZoneHandling.Utc
        }));

        Console.WriteLine(json.ToString());

        Console.Read();
    }
}

class Class2
{
    public DateTimeOffset time = new DateTimeOffset(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(14663484000000000));

    public DateTimeOffset time2 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(14663484000000000);

    public DateTime time3 = new DateTime(14663484000000000);
}

这是输出:

{
    "time": "2016-06-19T08:00:00-07:00",
    "time2": "2016-06-19T08:00:00-07:00",
    "time3": "0047-06-20T15:00:00Z"
}

这是我要获取的输出:

{
    "time": "2016-06-19T15:00:00+00:00",
    "time2": "2016-06-19T15:00:00+00:00",
    "time3": "0047-06-20T15:00:00+00:00"
}

如您所见,DateTimeOffset属性根本不会转换. DateTime是,但是使用Z指示时区,而我正在尝试使用+00:00.

As you can see, the DateTimeOffset properties are not converted at all. The DateTime is, but the timezone is indicated using Z whereas I'm trying to use +00:00.

推荐答案

在您的代码中,您正在执行以下操作:

In your code, you are doing the following:

  1. 使用与DateTime相关的特定序列化设置将Class2的实例序列化为JSON字符串.
  2. 不使用这些设置反序列化为JToken层次结构 .
  3. (对层次结构进行了其他修改-未显示.)
  4. 在不使用这些设置的情况下,再次将JToken层次结构序列化为最终字符串(通过json.ToString()).
  1. Serializing an instance of Class2 to a JSON string using specific DateTime-related serialization settings.
  2. Deserializing to a JToken hierarchy without using those settings.
  3. (Making additional modifications to the hierarchy - not shown.)
  4. Serializing the JToken hierarchy to a final string (via json.ToString()) again without using those settings.

执行此操作时,在步骤#1中选择的日期的格式设置会丢失.

When you do, formatting settings for dates chosen in step #1 get lost.

要解决此问题,每次在JSON字符串表示形式上进行序列化或从JSON字符串表示形式进行序列化时,都需要应用设置,因为正如

To solve this, you need to apply the settings every time you serialize from or to a JSON string representation, since, as explained in this documentation page, JSON does not have an "official" format for dates. Because of this, Json.NET applies heuristics for recognizing and formatting dates whenever it converts from and to a JSON string representation - which you are doing not once but thrice.

您可以这样做:

var settings = new JsonSerializerSettings()
{
    DateParseHandling = DateParseHandling.DateTimeOffset,
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Utc
};

// Generate initial serialization
var initialString = JsonConvert.SerializeObject(foo, settings);

// Parse back to JToken
var json = JsonConvert.DeserializeObject<JObject>(initialString, settings);

// Make modifications as required
// json["foo"] = "bar";

// Generate final JSON.
var finalString = JsonConvert.SerializeObject(json, Formatting.Indented, settings);

要提高效率,可以使用 JToken.FromObject() (或 JObject.FromObject() (如果愿意)来生成JToken层次结构,而无需需要创建和解析初始字符串表示形式:

To improve efficiency, you could use JToken.FromObject() (or JObject.FromObject() if you prefer) to generate the JToken hierarchy without needing to create and parse an initial string representation:

var settings = new JsonSerializerSettings()
{
    DateParseHandling = DateParseHandling.DateTimeOffset,
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    DateTimeZoneHandling = DateTimeZoneHandling.Utc
};

var json = JToken.FromObject(foo, JsonSerializer.CreateDefault(settings));

// Make modifications as required
// json["foo"] = "bar";

// Generate final JSON.
var finalString = JsonConvert.SerializeObject(json, Formatting.Indented, settings);

但是请注意,出于解释而不是"2016-06-19T15:00:00+00:00"格式输出UTC DateTime. >这里.如果您需要将UTC DateTime属性以DateTimeOffset格式序列化,则可能需要使用

Note, however, that Json.NET will output a UTC DateTime in the format "0047-06-20T15:00:00Z" rather than "2016-06-19T15:00:00+00:00" for reasons explained here. If you need your UTC DateTime properties to be serialized in DateTimeOffset format you might need to use a custom converter.

这篇关于序列化时,Json.Net弄乱了DateTimeOffset的时区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆