Handling time zones in .NET
Did you know there’s a DateTimeOffset type in .NET for storing timestamps with time zone information? I didn’t until a few months ago — the need for awareness just never came up, working mostly on internal software for geographically close audiences. Despite working with .NET for a long time, I still learn new things every day, and that’s one of my favorite things about programming.
If you’re a .NET developer to whom this sounds new, then you’re one of today’s lucky ten thousand.
Why do I need to care about time zones?
Maybe you don’t, it depends on what you’re working on and what you’re trying to do. Writing log entries for a desktop application somewhere on disk? It probably makes sense for them to be local time. Doing the same, but for a globally distributed online service? Maybe not so much. Time zones are a fabulously complex subject, and we’re fortunate to have high level languages and frameworks like .NET that will take a string and seamlessly convert it into your local time zone without you ever having to think about it:
You can ToUniversalTime() a DateTime to go from local to UTC, and ToLocalTime() to go back, but that’s the extent of what DateTime can do — local and UTC only. What if we want to parse that string above while keeping its time zone intact?
Enter DateTimeOffset
That’s exactly what DateTimeOffset lets you do. Modifying the example above we get:
Which, if you’re in the business of serializing and deserializing timestamps to and from strings, will preserve the original time zone information for you.
Using DateTimeOffset with JSON.NET
What originally got me down this rabbit hole was reading some JSON data from a web service, realizing that it was converting timestamps to local time, and trying to figure out how to control that. After realizing it was a feature of .NET itself, and not the ever popular JSON.NET library I was using, my question then became, “how do I get JSON.NET to parse timestamps as DateTimeOffsets?” the answer to which is simple: by specifying a JsonSerializerSettings object with DateParseHandling.DateTimeOffset.
And with that, I leave you with the .NET Fiddle I was experimenting with that led me to make this post, and some articles I found along the way:
