序列化时,Json.Net弄乱了DateTimeOffset的时区 [英] Json.Net messes up timezones for DateTimeOffset when serializing
问题描述
我看了很多相关问题,但似乎没有一个对我有用.
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:
- 使用与
DateTime
相关的特定序列化设置将Class2
的实例序列化为JSON字符串. - 不使用这些设置反序列化为
JToken
层次结构 . - (对层次结构进行了其他修改-未显示.)
- 在不使用这些设置的情况下,再次将
JToken
层次结构序列化为最终字符串(通过json.ToString()
).
- Serializing an instance of
Class2
to a JSON string using specificDateTime
-related serialization settings. - Deserializing to a
JToken
hierarchy without using those settings. - (Making additional modifications to the hierarchy - not shown.)
- Serializing the
JToken
hierarchy to a final string (viajson.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屋!