15

I'm parsing some JSON in C# using JSON.NET. One of the fields in the JSON is a date/time, like this:

{
    "theTime":"2014-11-20T07:15:11-0500",
    // ... a lot more fields ...
}

Note that the time part is 07:15:11 (TZ of GMT-5 hrs)

I parse the JSON from a stream like this:

 using (var streamReader = new StreamReader(rcvdStream))
 {
     JsonTextReader reader = new JsonTextReader(streamReader);
     JsonSerializer serializer = new JsonSerializer();
     JObject data = serializer.Deserialize<JObject>(reader);
     //...
  }

Then access the time:

DateTime theTime = (DateTime)data["theTime"];

However, this gives me this DateTime object:

{20/11/2014 12:15:11}
Date: {20/11/2014 00:00:00}
Day: 20
DayOfWeek: Thursday
DayOfYear: 324
Hour: 12
Kind: Local
Millisecond: 0
Minute: 15
Month: 11
Second: 11
Ticks: 635520825110000000
TimeOfDay: {12:15:11}
Year: 2014

I need to know the original local time and tz offset, but I seem to have lost that information in the deserialization process, and it is giving me the time in what I presume is my local time (I'm in the UK, so currently at GMT+0).

Is there a way for me to preserve the timezone information when deserializing?

EDIT: added more detail about how I'm deserializing.

Dave W
  • 1,061
  • 3
  • 16
  • 29
  • How are you creating your `serializer` object? – DavidG Nov 20 '14 at 15:36
  • Have you tried deserializing/casting it to a DateTimeOffset rather than a DateTime? – J. Steen Nov 20 '14 at 15:37
  • I've updated the post to show how I'm creating the serializer object. – Dave W Nov 20 '14 at 15:40
  • 1
    I would recommend converting to UTC, sending/receiving in UTC, and converting to local time on the client side for display purposes. – Haney Nov 20 '14 at 15:40
  • Casting to a DateTimeOffset is still wrong - the time is 12:15 and offset is 00:00. – Dave W Nov 20 '14 at 15:42
  • I have no control over the source JSON, so I can't change it to be UTC. – Dave W Nov 20 '14 at 15:42
  • 1
    Note that the post suggested as the duplicate of this one, while it is originally asking about timezone codes, has the answer you're looking for: your string has the timezone offset, and it shows how to correctly parse a `DateTime` containing a timezone offset. – Peter Duniho Nov 20 '14 at 23:55
  • 4
    I don't agree that this is a duplicate question. The other answer linked to is about parsing DateTime but not from the Json deserializer. For that to be useful he'd have to change the deserializer to just return the date as a string, and then parse the string wherever needed. `serializer.DateParseHandling = DateParseHandling.None;` – Cary Oct 13 '15 at 00:18
  • 1
    Also mentioning that question is not duplicate. The other question is about timezone abbreviations like "CET", this one is about numeric timezones, like "+01:00". Also note that many know JSON.NET as Newtonsoft.Json. and that it handles timezones "Z" and "+00:00" differently (only "Z" is treated as actual UTC!) – Erik Hart Nov 20 '20 at 12:36
  • The question is a duplicate of https://stackoverflow.com/questions/246498/creating-a-datetime-in-a-specific-time-zone-in-c-sharp, but not currently specified question – Michael Freidgeim Jul 14 '22 at 22:30

1 Answers1

25

I would use DateTimeOffset for this instead. DateTime doesn't have any useful time zone information associated with it.

You can deserialize to DateTimeOffset instead by changing serializer.DateParseHandling:

JsonSerializer serializer = new JsonSerializer();
serializer.DateParseHandling = DateParseHandling.DateTimeOffset;

JObject data = serializer.Deserialize<JObject>(reader);

var offset = (DateTimeOffset)data["theTime"];

Console.WriteLine(offset.Offset);    // -5:00:00
Console.WriteLine(offset.DateTime);  // 11/20/2014 7:15:11 AM

Example: https://dotnetfiddle.net/I9UAuC

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307