使用JSON.NET来解析格式Date(epochTime-offset)的json日期 [英] Use JSON.NET to parse json date of format Date(epochTime-offset)

查看:241
本文介绍了使用JSON.NET来解析格式Date(epochTime-offset)的json日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#中使用Json.net 7.0.1来使用休息API。麻烦的是API在JSON响应中使用的日期格式。它看起来像这样:

  /日期(1445301615000-0700)/ 
pre>

这意味着代表UTC时间2015-10-19 17:40:15



如果您将1445301615000插入时代转换器,您会发现它是2015-10- 20 00 :40:15。所以在UTC之前提前7个小时。那么它们包括-0700,可能是将其反向回到UTC。所以,为了给我一个UTC时间,他们发送UTC + 7-0700。为什么他们这样做我不知道,但我不能改变。



我的问题是,如何最好地使Json.NET解析日期字符串和提出DateTime为 2015-10-19 17:40:15 UTC。我可以编写一个自定义的JsonConverter来劫持该值并手动操作它,但是我想知道是否有更多的本地方法。



我尝试更改 JsonSerializerSettings DateTimeZoneHandling 属性到其所有不同的值。将其设置为Utc只是忽略时区偏移,产生 2015-10-20 00:40:15 。将其设置为本地,未指定或往返所有收益 2015-10-19 20:40:15 ,我相信是因为我的本地时区是UTC-4,所以它正在尝试将该调整应用于2015-10-20 00:40的主日期值。



我还考虑使用 DateFormatString 属性来表示预期的日期字符串格式。但是我找不到正确的格式字符串字符来代表这个epochtime-偏移格式。



这是一个简化的例子:

  
string json = @{'Name':'John',
'LastSeen':'/ Date(1445301615000-0700)/'}; // 1445301615000 = 2015-10-20 00:40:15

person = JsonConvert.DeserializeObject< Person>(json);
Console.WriteLine(person.LastSeen); // 10/19/2015 8:40:15 PM Kind = Local

person = JsonConvert.DeserializeObject< Person>(json,new JsonSerializerSettings {DateFormatHandling = DateFormatHandling.MicrosoftDateFormat});
Console.WriteLine(person.LastSeen); // 10/19/2015 8:40:15 PM Kind = Local

person = JsonConvert.DeserializeObject< Person>(json,new JsonSerializerSettings {DateTimeZoneHandling = DateTimeZoneHandling.Utc});
Console.WriteLine(person.LastSeen); // 10/20/2015 00:40:15 PM Kind = Utc

//在所有三个中,-0700部分都被忽略。我想要人。最后是10/19/2015 17:40:15。

再次,我可以知道API会给我UTC + 7并进行调整我得到真正的UTC。但是我想知道Json.NET是否有一种本地方式来处理这种类型的日期字符串。

解决方案


/日期(1445301615000-0700)/



这意味着代表UTC时间2015-10-19 17:40:15


对不起,这是不正确的。 UTC时间是 2015-10-20 00:45:15 。您的值对应于本地时间,在该时刻的 -07:00 偏移的时区。



在此螺丝格式中,时间戳部分仍然基于仅在UTC。偏移量是额外的信息。它不会更改时间戳。您可以给出不同的偏移量,或者完全省略它,并且它仍然是一段时间。



以下所有内容都是等效的,关于时间点。

  /日期(1445301615000-0700)/ 
/日期(1445301615000)/
2015-10 -20T00:40:15Z
2015-10-19T17:40:15-07:00



<请注意,在ISO格式中,偏移量不改变该值,但MS格式不会。



如果您没有使用这种格式,则最好,因为ISO8601是JSON的一个更为明智的选择。但是,如果你坚持使用它,那么最好不要将它反序列化为 DateTime 。相反,请使用 DateTimeOffset



考虑:

  string s =\/ Date(1445301615000-0700)/ \; 
DateTime dt = JsonConvert.DeserializeObject< DateTime>(s);
Console.WriteLine(dt.Kind); //本地

这不是很好。基本上,如果有任何偏移量,它认为这是您当地的时区,可能是这样,但可能不是。

  string s =\/ Date(1445301615000)/ \; 
DateTime dt = JsonConvert.DeserializeObject< DateTime>(s);
Console.WriteLine(dt.Kind); // Utc

没关系,但是你没有跟踪当地时间。 >

  string s =\/ Date(1445301615000-0700)/ \; 
DateTimeOffset dto = JsonConvert.DeserializeObject< DateTimeOffset>(s);
Console.WriteLine(dto); // 10/19/2015 5:40:15 PM -07:00

那好多了如果你确实想要一个UTC DateTime ,那么:

  string s =\/日期(1445301615000-0700)/ \; 
DateTimeOffset dto = JsonConvert.DeserializeObject< DateTimeOffset>(s);
DateTime utc = dto.UtcDateTime;
Console.WriteLine(utc); // 10/20/2015 12:40:15 AM

所以关键的教训是,不管格式,如果数据中存在时区偏移信息,则反序列化为 DateTimeOffset 。在某些情况下,使用 DateTime 可能会工作,您要求.NET解释偏移并应用默认行为,这通常不会是 行为。


I am using Json.net 7.0.1 in C# to consume a rest API. The trouble is with the date format the API uses in its JSON response. It looks like this:

/Date(1445301615000-0700)/

That is meant to represent a UTC time of 2015-10-19 17:40:15

If you plug 1445301615000 into an epoch time converter, you see that it is 2015-10-20 00:40:15 . So it is 7 hours ahead of UTC. Then they include the -0700 presumably to offset that back to UTC. So, in an effort to give me a UTC time, they are sending me UTC+7-0700. Why they do it this way I have no idea, but I can't change that.

My question is, how best to make Json.NET parse that date string and come up with a DateTime of 2015-10-19 17:40:15 UTC. I can write a custom JsonConverter to hijack the value and manipulate it manually, but I was wondering if there is a more native method.

I have tried changing the JsonSerializerSettings DateTimeZoneHandling property to all its different values. Setting it to Utc just ignores the time zone offset, yielding 2015-10-20 00:40:15. Setting it to Local, Unspecified, or RoundtripKind all yield 2015-10-19 20:40:15, which I believe is because my local timezone is UTC-4, so it is trying to apply that adjustment to the main date value of 2015-10-20 00:40.

I also considered using the DateFormatString property to represent the expected date string format. But I could not find the right format string characters to represent this epochtime-offset format.

Here's a simplified example:

Person person;
string json = @"{ 'Name': 'John', 
                  'LastSeen':'/Date(1445301615000-0700)/' }";   // 1445301615000 = 2015-10-20 00:40:15

person = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine(person.LastSeen);     // 10/19/2015 8:40:15 PM    Kind = Local

person = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat });
Console.WriteLine(person.LastSeen);     // 10/19/2015 8:40:15 PM    Kind = Local

person = JsonConvert.DeserializeObject<Person>(json, new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.Utc });
Console.WriteLine(person.LastSeen);     // 10/20/2015 00:40:15 PM    Kind = Utc

// In all three, the -0700 portion is being ignored. I'd like person.LastSeen to be 10/19/2015 17:40:15.

Again, I could just know that the API is going to give me UTC+7 and do the adjustment myself to get real UTC. But I wondered if Json.NET has a native way to handle this type of date string.

解决方案

/Date(1445301615000-0700)/

That is meant to represent a UTC time of 2015-10-19 17:40:15

Sorry, that's incorrect. The UTC time is 2015-10-20 00:45:15. Your value corresponds to the local time, in a time zone with a -07:00 offset at that instant.

In this screwy format, the timestamp portion is still based solely on UTC. The offset is extra information. It doesn't change the timestamp. You can give a different offset, or omit it entirely and it's still the same moment in time.

All of the following are equivalent, with regard to point-in-time.

/Date(1445301615000-0700)/
/Date(1445301615000)/
2015-10-20T00:40:15Z
2015-10-19T17:40:15-07:00

Notice that in in the ISO format, the offset does change the value, but in the MS format it does not.

It would be best if you did not use this format, as ISO8601 is a much saner choice for JSON. However if you're stuck with it, then it's best not to deserialize it to a DateTime. Instead, use a DateTimeOffset.

Consider:

string s = "\"/Date(1445301615000-0700)/\"";
DateTime dt = JsonConvert.DeserializeObject<DateTime>(s);
Console.WriteLine(dt.Kind); // Local

That's no good. basically, if there is any offset, it thinks it's your local time zone, which it might be, but it might not be.

string s = "\"/Date(1445301615000)/\"";
DateTime dt = JsonConvert.DeserializeObject<DateTime>(s);
Console.WriteLine(dt.Kind); // Utc

This is ok, but you've lost track of that local time.

string s = "\"/Date(1445301615000-0700)/\"";
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>(s);
Console.WriteLine(dto); // 10/19/2015 5:40:15 PM -07:00

That's much better. And if you do indeed want a UTC DateTime, then:

string s = "\"/Date(1445301615000-0700)/\"";
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>(s);
DateTime utc = dto.UtcDateTime;
Console.WriteLine(utc); // 10/20/2015 12:40:15 AM

So the key lesson is, regardless of format, if there is time zone offset information present in the data, then deserialize to DateTimeOffset. While using DateTime might work in some cases, you are asking .NET to interpret the offset and apply default behavior, which often will not be the desired behavior.

这篇关于使用JSON.NET来解析格式Date(epochTime-offset)的json日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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