By Felipe Miosso

2013-12-09 13:31:25 8 Comments

I'm reading a lot about timezone, offset, utc, local time, javascript functions, DST, bacon and I 'm trying to put this all together to build a solid/correct structure for my app.

Suppose my app is something like StackOverflow.

That is how I'm doing ...

  • The server is in another country, so I set it to UTC 00:00.
  • I'm storing date as DateTimeOffset.
  • I'm not storing TimeZoneID.
  • Date is being sent to the client in this format: 2012-07-19T14:30:00-03:00.
  • I'm using angular filter to convert it to local time.

I have a few questions about it ...

1º Server TimeZone?

About my server (single server) ... should it be running with a "neutral" UTC (+00:00)? And what if, in the future, we move to a farm where servers run on different locations?

2º What should I store?

Currently, I'm storing just date as DateTimeOffset. I'm reading about saving the TimeZoneID but I'm seeing no use at all for this. Am I missing something?

Or should I store date as DateTimeUtc with a TimeZoneID and manually convert every date with the TimeZone class?

3º How to convert to local time?

Is it safe to convert data on the client? Or date conversions should be always on the server side?

4º About DST.

Using my current approach. Will DST be respected?


@Matt Johnson-Pint 2013-12-09 18:26:05

One very important thing to understand about date/time is that there is no one right way for doing everything. The common answer "use UTC" is not always applicable. Context is very important, and there are different techniques and approaches based on what the values you are working with are representing. If you could elaborate on what they are used for in your application, I will update my answer accordingly. In the meantime, I'll try to address the specific points you have brought up already:

#1 - Server Time Zone

Keeping your server at UTC is a best practice, and it is what you can expect from cloud providers like Azure or AWS also. But it isn't something that you should be dependent on. Your server should be able to be set to any time zone without it affecting your application. As long as the clock is in sync with an NTP server, choice of time zone should not matter.

So how do you ensure that? Simple, just make sure your application avoids all of the following:

  • DateTime.Now
  • DateTimeKind.Local
  • TimeZone (the entire class)
  • TimeZoneInfo.Local
  • DateTime.ToLocalTime()
  • DateTime.ToUniversalTime() (because it assumes the input is local)
  • Misc. other methods that assume a local input or output, such as TimeZoneInfo.ConvertTimeToUtc(DateTime) (this particular overload doesn't take a time zone, so it assumes the local time zone)

See also my blog post: The Case Against DateTime.Now.

Note that I didn't include DateTimeOffset.Now in the list. Although it's a little bit of a design smell, it is still "safe" to use.

#2 - What to store

I suggest you read my answer to DateTime vs DateTimeOffset. It should clarify some things. Without regurgitating the whole thing, the main point is that while both represent a point in time accurately, a DateTimeOffset provides perspective, while a UTC DateTime does not.

You also asked when you should store a TimeZoneInfo.Id. There are at least two scenarios where this is required:

  • If you are recording events in the past or present, and you plan on allowing modifications to the recorded timestamps. You need the time zone to determine what the new offset should be, or how the new input converts back to UTC.

  • If you are scheduling time out into the future, you will need the time zone as part of the recurrence pattern (even for a single occurrence). See here and here also, (while for other languages, the same principles apply).

Again, the exact answer depends on what exactly the timestamps represent. There is no one ring to rule them all.

#3 - Client Safety

If it's a .NET client, sure you can convert there. But I think you are asking about a JavaScript client browser.

"Safe" is a relative term. If you're asking for exact perfectness, then no. JavaScript isn't safe for that, due to an error in the ECMAScript specification (ES1 through ES5.1. It is being worked on for ES6). You can read more in my blog post: JavaScript Date type is horribly broken.

However, if you are working with relatively current data, and the users of your application are not in a part of the world where time zones are volatile, or you don't require precise results 100% of the time, then you can "safely" use JavaScript to convert to the user's local time zone.

You might avoid some of these issues with libraries that implement the IANA TZDB in JavaScript, such as the ones I list here. But many of them are still dependent on JS Date, so they still have issues. (Side note - I'm working on a JS library that will counter this, but it is not ready to share yet).

Conversions on the server side are a much better choice, as long as you can ask the user for their time zone. Most of the time, I think this is doable.

You might consider asking using a map-based timezone picker, such as this one or this one. Both of which will require you use IANA time zones, which for .NET means using Noda Time, which is a great idea anyway (IMHO).

#4 - Daylight Saving Time

With your current approach, DST will be respected within the definition of the current DST rules for the time zone the user has set for their local browser. (Again, refer to my blog post for why this is the case).

A conversion from any value with an offset (whether -03:00 or Z) that passes through the Date object (which I believe an Angular filter will do), will properly convert to the specific unix timestamp.

The errors that would crop up with DST conversions for prior DST rules are because going from the unix timestamp inside the Date object to the local time zone will always assume that the current DST rule is applicable, even if the time fell into a period that had a different rule.

@Felipe Miosso 2013-12-09 18:35:55

you are awesome! The app will be something like Stackoverflow.

@Matt Johnson-Pint 2013-12-09 18:39:56

So as long as the timestamps involved are "the time an event took place" (such as a posting time, comment time, etc.) then you can simply store a UTC DateTime. Time zone IDs aren't required since you aren't going to modify history, and offsets aren't harmful but aren't necessarily useful either.

@Matt Johnson-Pint 2013-12-09 18:42:35

Also note that S.O. avoids time zone conversions by using the "10 minutes ago" style of output, and only showing UTC values. Also, they base their daily cycle for points and other stuff on the UTC day, which has been disputed as possibly being unfair on meta a few times, but that's what they've decided on.

@Matt Johnson-Pint 2013-12-09 18:45:37

One place I can think that might change your mind to use DateTimeOffset instead, would be if you want to generate statistical reports that show the most active times of day that people post. UTC day is one thing, but you might be interested in more relative local periods, like "morning", "midday", "evening", "nighttime". To do that, you need that "perspective" that DateTimeOffset can provide.

@Felipe Miosso 2013-12-09 18:48:45

That is exactly what I was looking for. Thank you very much for that! You save me a few days of testing and searching! You sir, deserve all the bacon in the world. Thank you again!!

@ken2k 2013-12-09 13:38:35

This actually depends on the actual application you're writing, but the most simple/robust approach IMO is to store/compute all your dates using UTC, and convert it back to the local time zone when you display it to the user.

@Felipe Miosso 2013-12-09 13:40:51

It is safe to convert using javascript?

@Mike Perrenoud 2013-12-09 13:42:47

@FelipeMiosso, what would be inherently unsafe about that operation?

@ken2k 2013-12-09 13:42:58

@FelipeMiosso Not sure what you mean by 'safe', but if your application is a web application, you could convert your UTC dates to the local time zone using javascript. See…

@Felipe Miosso 2013-12-09 13:49:02…. Maybe I misunderstood that, but ... in the "don't" section. It's saying that it's not good to handle date on the client.

Related Questions

Sponsored Content

10 Answered Questions

[SOLVED] DateTime vs DateTimeOffset

46 Answered Questions

[SOLVED] How do I remove a property from a JavaScript object?

86 Answered Questions

[SOLVED] How do JavaScript closures work?

39 Answered Questions

[SOLVED] How do I return the response from an asynchronous call?

97 Answered Questions

[SOLVED] How can I remove a specific item from an array?

  • 2011-04-23 22:17:18
  • Walker
  • 7125959 View
  • 8647 Score
  • 97 Answer
  • Tags:   javascript arrays

23 Answered Questions

[SOLVED] Create a Date with a set timezone without using a string representation

58 Answered Questions

[SOLVED] How do I check if an element is hidden in jQuery?

58 Answered Questions

[SOLVED] How do I redirect to another webpage?

29 Answered Questions

[SOLVED] How do you convert a JavaScript date to UTC?

  • 2009-06-04 03:54:58
  • dthrasher
  • 839100 View
  • 613 Score
  • 29 Answer
  • Tags:   javascript date utc

3 Answered Questions

Sponsored Content