0

I am receiving the following string from an api:

{ "CallTime" : "2018-02-23T16:00:01.806Z" }

In my database, I want to store all date/times in zulu time. To accomplish this, I am using DateTime.Parse to convert this string into a DateTime object. Then, I use the ToUniversalTime() to change the time into zulu time (and then I store that in the database).

However, I'm not sure if I am understanding the interpretation of time zones correctly. If I look at the results, this is what confuses me:

DateTime.Parse("2018-02-23T16:00:01.806Z") /* = 2/23/2018 10:00:01 AM */
DateTime.Parse("2018-02-23T16:00:01.806Z").ToUniversalTime() /* = 2/23/2018 4:00:01 PM */

Isn't the original string already in zulu time? I would think these two values should be the same. There is no indication of a time zone in the original string, so wouldn't the Parse function assume zulu time automatically? Or, does Parse use the local system timezone and use that to convert the string to an object?

Matt Spinks
  • 6,380
  • 3
  • 28
  • 47
  • https://msdn.microsoft.com/en-us/library/system.datetime.touniversaltime(v=vs.110).aspx – Hackerman Feb 26 '18 at 19:54
  • https://stackoverflow.com/questions/1201378/how-does-datetime-touniversaltime-work – Hackerman Feb 26 '18 at 19:54
  • https://learn.microsoft.com/en-us/scripting/javascript/date-and-time-strings-javascript That's an ISO 8601 date, the trailing `Z` specifies UTC timezone. – Gusman Feb 26 '18 at 19:55
  • Possible duplicate of [How does DateTime.ToUniversalTime() work?](https://stackoverflow.com/questions/1201378/how-does-datetime-touniversaltime-work) – CDove Feb 26 '18 at 19:55
  • `var dt = (DateTime)JObject.Parse(yourstring)["CallTime"];` Then see the *dt.Kind* – Eser Feb 26 '18 at 19:56
  • 2
    Assuming you have the option, _always_ use `DateTimeOffset` instead of `DateTime` (for everything, storage, calculation, display, all of it). MSDN has a detailed blog article from 2012 [here](https://blogs.msdn.microsoft.com/davidrickard/2012/04/06/datetime-and-datetimeoffset-in-net-good-practices-and-common-pitfalls/). Basically `DateTime` is still around mainly because it would break too many things to get rid of it. – McGuireV10 Feb 26 '18 at 20:07
  • If you care enough about date and time and timezones that you're asking this kind of question you should probably be using [NodaTime](https://nodatime.org/) instead of the built-in .NET classes for this. – Lasse V. Karlsen Feb 27 '18 at 07:10

2 Answers2

1

The correct answer is: yes it does.

As Many comments are pointing out, DateTime.Parse() uses the DateTimeKind.Local by default-> 2/23/2018 10:00:01 AM When you call ToUniversalTime(), you get the UTC-time again-> 4PM

Nikolaus
  • 1,859
  • 1
  • 10
  • 16
1

Rather than calling ToUniversalTime, consider changing your code to pass DateTimeStyles.RoundTripKind. This is specifically designed to evaluate the string and set the kind accordingly. In other words, when it sees Z, it will set the kind to DateTimeKind.Utc and give you a UTC-based value. If it sees an offset, it will adjust for the offset, convert to local time and set DateTimeKind.Local. If it sees neither then it sets DateTimeKind.Unspecified.

DateTime.Parse("2018-02-23T16:00:01.806Z", CultureInfo.InvariantCulture,
                                           DateTimeStyles.RoundTripKind);

Also, you may find that using DateTimeOffset is more intuitive and practical than DateTime. You also don't need to worry about setting the style if you do.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575