Use JSON.NET to parse json date Date format (epochTime-offset)

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

/Date(1445301615000-0700)/ 

It means UTC time 2015-10-19 17:40:15

If you connect 1445301615000 to the epoch time converter , you will see that it is 2015-10-20 00 : 40: 15. Thus, it is 7 hours more than UTC. They then include -0700, presumably to offset this before UTC. Therefore, to give me UTC time, they send me UTC + 7-0700. Why they do this, I have no idea, but I can’t change that.

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

I tried to change the JsonSerializerSettings DateTimeZoneHandling property to all of its different values. By setting it, Utc simply ignores the time zone offset, getting 2015-10-20 00:40:15 . Setting it to Local, Unspecified or RoundtripKind, everyone gives 2015-10-19 20:40:15 , which I believe is due to the fact that my local time zone is UTC-4, so he is trying to apply this setting to the main date value 2015-10-20 00:40.

I also looked at using the DateFormatString property to represent the expected date string format. But I could not find the correct format string characters to represent this time-offset format.

Here is 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 tuning myself to get the real UTC. But I wondered if Json.NET has its own way of writing this type of date string.

+4
source share
2 answers

/ Date (1445301615000-0700) /

It means UTC time 2015-10-19 17:40:15

Sorry, this is wrong. UTC time 2015-10-20 00:45:15 . Your value corresponds to local time in the time zone with an offset of -07:00 at that moment.

In this wine format, part of the timestamp is still based solely on UTC. Offset is additional information. It does not change the timestamp. You can give another bias or completely lower it, and this is all the same point in time.

All of the following are equivalent with respect to a point in time.

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

Please note that in the ISO format, the offset changes the value, but in the MS format this is not so.

It would be better if you did not use this format, since ISO8601 is a much more reasonable choice for JSON. However, if you are stuck with it, it is best not to deserialize it to a DateTime . Use DateTimeOffset instead.

Consider:

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

This is not good. basically, if there is any bias, he thinks it is your local time zone as it may be, but it may not be so.

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

This is normal, but you have lost control of this 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 

This is much better. And if you really 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 main lesson, regardless of format, if the data contains information about the time zone offset, then deserialize to DateTimeOffset . Although using DateTime may work in some cases, you are asking .NET to interpret the offset and apply default behavior, which is often not desirable.

+5
source

-hhmm indicates that local time was serialized, and not UTC..NET time, like many other platforms, recognizes the concept of time zones. For example, in .NET, the DateTime class has a property indicating which date / time you are dealing with. You can explicitly build date / time of different kinds. The debugger is terrible without specifying this, but you can see it with the following code.

 var dt1 = new DateTime(2015, 01, 01, 00, 00, 00); // defaults to DateTimeKind.Unspecified var dt2 = new DateTime(2015, 01, 01, 00, 00, 00, DateTimeKind.Local); var dt3 = new DateTime(2015, 01, 01, 00, 00, 00, DateTimeKind.Utc); var dt4 = new DateTime(2015, 01, 01, 00, 00, 00, DateTimeKind.Unspecified); Debug.WriteLine(dt1.Kind); // writes "Unspecified" Debug.WriteLine(dt2.Kind); // writes "Local" Debug.WriteLine(dt3.Kind); // writes "Utc" Debug.WriteLine(dt4.Kind); // writes "Unspecified" 

Then you can see the effect that DateTimeKind has on Json with the following

 // local time -- default datetime handling from JSON.NET { var dateTime = DateTime.Now; var jsonObject = new JObject {["dateTime"] = dateTime}; var jsonString = jsonObject.ToString(); Debug.WriteLine(jsonString); // uses "2015-10-19T18:13:53.4698565-04:00" form } // UTC time -- default datetime handling from JSON.NET { var dateTime = DateTime.Now.ToUniversalTime(); var jsonObject = new JObject {["dateTime"] = dateTime }; var jsonString = jsonObject.ToString(); Debug.WriteLine(jsonString); // uses "2015-10-19T22:13:53.5166571Z" form } // local time -- Microsoft-like datetime handling from JSON.NET { var dateTime = DateTime.Now; var jsonObject = new JObject {["dateTime"] = dateTime }; var jsonString = JsonConvert.SerializeObject(jsonObject, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); Debug.WriteLine(jsonString); // uses "/Date(1445292833516-0400)/" format } // local time -- Microsoft-like datetime handling from JSON.NET { var dateTime = DateTime.Now.ToUniversalTime(); var jsonObject = new JObject {["dateTime"] = dateTime }; var jsonString = JsonConvert.SerializeObject(jsonObject, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }); Debug.WriteLine(jsonString); // uses "/Date(1445292833579)/" form } 
+2
source

Source: https://habr.com/ru/post/980886/


All Articles