Categories
datetime datetimeoffset dst timezone utc

Daylight saving time and time zone best practices [closed]

2150

I am hoping to make this question and the answers to it the definitive guide to dealing with daylight saving time, in particular for dealing with the actual change overs.

If you have anything to add, please do

Many systems are dependent on keeping accurate time, the problem is with changes to time due to daylight savings – moving the clock forward or backwards.

For instance, one has business rules in an order taking system that depend on the time of the order – if the clock changes, the rules might not be as clear. How should the time of the order be persisted? There are of course an endless number of scenarios – this one is simply an illustrative one.

  • How have you dealt with the daylight saving issue?
  • What assumptions are part of your solution? (looking for context here)

As important, if not more so:

  • What did you try that did not work?
  • Why did it not work?

I would be interested in programming, OS, data persistence and other pertinent aspects of the issue.

General answers are great, but I would also like to see details especially if they are only available on one platform.

9

  • 2

    @abatishchev – This way GETDATE() on SQL will be UTC (as will DateTime.Now). And the server will not be effected by any sort of automatic DST changes.

    – Oded

    May 31, 2012 at 15:23

  • 4

    @Oded: I can agree if “on server” will be added. But still that can affect another applications which need local time. By this and other reasons I think it’s better to request Utc time explicitly.

    Jun 1, 2012 at 6:47

  • 7

    UTC is preferred to GMT, both because it is more precisely defined and because GMT definitions are messed up on some operating systems. It’s common for people to treat the terms “GMT” and “UTC” as interchangeable but they aren’t entirely. For almost any software / systems purpose, use UTC. See stackoverflow.com/questions/2292334/…

    Oct 1, 2012 at 10:04

  • 7

    @JoshStodola — Jon Skeet’s ‘answer‘.

    Mar 31, 2013 at 2:36


  • 2

    @Oded you can’t assume the server will be on UTC, I’ve seen production servers where the timezone was “UTC” but had DST applied so was actually UTC+1 for over half the year. Agree with @abatishchev to be explicit and use DateTime.UtcNow and GETUTCDATE(), it also shows other devs that you’ve actually thought about it

    – ono2012

    Apr 22, 2016 at 13:45


338

+50

I’m not sure what I can add to the answers above, but here are a few points from me:

Types of times

There are four different times you should consider:

  1. Event time: eg, the time when an international sporting event happens, or a coronation/death/etc. This is dependent on the timezone of the event and not of the viewer.
  2. Television time: eg, a particular TV show is broadcast at 9pm local time all around the world. Important when thinking about publishing the results (of say American Idol) on your website
  3. Relative time: eg: This question has an open bounty closing in 21 hours. This is easy to display
  4. Recurring time: eg: A TV show is on every Monday at 9pm, even when DST changes.

There is also Historic/alternate time. These are annoying because they may not map back to standard time. Eg: Julian dates, dates according to a Lunar calendar on Saturn, The Klingon calendar.

Storing start/end timestamps in UTC works well. For 1, you need an event timezone name + offset stored along with the event. For 2, you need a local time identifier stored with each region and a local timezone name + offset stored for every viewer (it’s possible to derive this from the IP if you’re in a crunch). For 3, store in UTC seconds and no need for timezones. 4 is a special case of 1 or 2 depending on whether it’s a global or a local event, but you also need to store a created at timestamp so you can tell if a timezone definition changed before or after this event was created. This is necessary if you need to show historic data.

Storing times

  • Always store time in UTC
  • Convert to local time on display (local being defined by the user looking at the data)
  • When storing a timezone, you need the name, timestamp and the offset. This is required because governments sometimes change the meanings of their timezones (eg: the US govt changed DST dates), and your application needs to handle things gracefully… eg: The exact timestamp when episodes of LOST showed both before and after DST rules changed.

Offsets and names

An example of the above would be:

The soccer world cup finals game
happened in South Africa (UTC+2–SAST)
on July 11, 2010 at 19:00 UTC.

With this information, we can historically determine the exact time when the 2010 WCS finals took place even if the South African timezone definition changes, and be able to display that to viewers in their local timezone at the time when they query the database.

System Time

You also need to keep your OS, database and application tzdata files in sync, both with each other, and with the rest of the world, and test extensively when you upgrade. It’s not unheard of that a third party app that you depend on did not handle a TZ change correctly.

Make sure hardware clocks are set to UTC, and if you’re running servers around the world, make sure their OSes are configured to use UTC as well. This becomes apparent when you need to copy hourly rotated apache log files from servers in multiple timezones. Sorting them by filename only works if all files are named with the same timezone. It also means that you don’t have to do date math in your head when you ssh from one box to another and need to compare timestamps.

Also, run ntpd on all boxes.

Clients

Never trust the timestamp you get from a client machine as valid. For example, the Date: HTTP headers, or a javascript Date.getTime() call. These are fine when used as opaque identifiers, or when doing date math during a single session on the same client, but don’t try to cross-reference these values with something you have on the server. Your clients don’t run NTP, and may not necessarily have a working battery for their BIOS clock.

Trivia

Finally, governments will sometimes do very weird things:

Standard time in the Netherlands was
exactly 19 minutes and 32.13 seconds
ahead of UTC by law from 1909-05-01
through 1937-06-30. This time zone
cannot be represented exactly using
the HH:MM format.

Ok, I think I’m done.

12

  • 7

    This answer has some great points, I especially wanted to point this out part “Recurring time: eg: A TV show is on every Monday at 9pm, even when DST changes” Storing times in UTC in the DB and then converting for display helps handle a lot of the tricky aspects of dealing with time zones. However, handling “recurring events” that cross DST barriers becomes much tougher.

    Aug 5, 2010 at 13:53


  • 47

    +1 for the Trivia. Keeping the content interesting makes this task more enjoyable, which may lead to increased productivity 🙂

    – Chris

    Jan 8, 2011 at 6:54

  • 5

    A lot of good stuff in this answer, but a few issues. 1) Many time zone abbreviations are ambiguous. see here 2) Not always do you want to store in UTC. Most of the time – yes, but context matters. In your terms, television time would not be stored in UTC. Also, sometimes its unlawful or against policy to not store the local time – which is where things like DateTimeOffset (or equivalent) come in handy. Otherwise, good write up.

    Jan 11, 2013 at 1:38

  • 1

    So, everyone agrees that the Joda library is by far the best tool available for the job. However, we need to keep updating (rebuilding) the JODA jar file as per this article (joda.org/joda-time/tz_update.html) in order to keep up to date with the latest timezone information. Is there any standard way of downloading the latest timezone data from IANA website (iana.org/time-zones) and rebuilding the joda library? In other words, is it possible to automate this process rather than doing it manually?

    Dec 13, 2013 at 9:36


  • 2

    The Netherlands trivia looks legit. ietf.org/rfc/rfc3339.txt section 5.8. Halfway figured someone was pulling our leg.

    – ruffin

    Jun 6, 2014 at 14:13

92

This is an important and surprisingly tough issue. The truth is that there is no completely satisfying standard for persisting time. For example, the SQL standard and the ISO format (ISO 8601) are clearly not enough.

From the conceptual point of view, one usually deals with two types of time-date data, and it’s convenient to distinguish them (the above standards do not) : “physical time” and “civil time“.

A “physical” instant of time is a point in the continuous universal timeline that physics deal with (ignoring relativity, of course). This concept can be adequately coded-persisted in UTC, for example (if you can ignore leap seconds).

A “civil” time is a datetime specification that follows civil norms: a point of time here is fully specified by a set of datetime fields (Y,M,D,H,MM,S,FS) plus a TZ (timezone specification) (also a “calendar”, actually; but lets assume we restrict the discussion to Gregorian calendar). A timezone and a calendar jointly allow (in principle) to map from one representation to another. But civil and physical time instants are fundamentally different types of magnitudes, and they should be kept conceptually separated and treated differently (an analogy: arrays of bytes and character strings).

The issue is confusing because we speak of these types events interchangeably, and because the civil times are subject to political changes. The problem (and the need to distinguish these concepts) becomes more evident for events in the future. Example (taken from my discussion here.

John records in his calendar a reminder for some event at datetime
2019-Jul-27, 10:30:00, TZ=Chile/Santiago, (which has offset GMT-4,
hence it corresponds to UTC 2019-Jul-27 14:30:00). But some day
in the future, the country decides to change the TZ offset to GMT-5.

Now, when the day comes… should that reminder trigger at

A) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00 ?

or

B) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00 ?

There is no correct answer, unless one knows what John conceptually meant
when he told the calendar “Please ring me at 2019-Jul-27, 10:30:00
TZ=Chile/Santiago
“.

Did he mean a “civil date-time” (“when the clocks in my city tell
10:30”)? In that case, A) is the correct answer.

Or did he mean a “physical instant of time”, a point in the continuus
line of time of our universe, say, “when the next solar eclipse
happens”. In that case, answer B) is the correct one.

A few Date/Time APIs get this distinction right: among them, Jodatime, which is the foundation of the next (third!) Java DateTime API (JSR 310).

3

  • 1

    Another point to consider which I’ve not seen addressed in APIs is that even when time and time zone are given, there are at least two plausible meanings for e.g. “13:00:00EDT”. It could be refer to something which is known to have occurred at 1pm local time, which was believed to have been Eastern Daylight Time, or something which is known to have occurred at the moment that Eastern time hit 13:00, which is believed to have occurred in a place observing Eastern Daylight Time. If one has many timestamps where the time-zone info may be wrong (e.g. digital camera files)…

    – supercat

    Oct 29, 2013 at 17:04

  • 1

    …knowing whether they reflect an accurate local time or global time may be important in determining how to correct them.

    – supercat

    Oct 29, 2013 at 17:04

  • 6

    Clearly John wants A) because people go to work at 8:30, whatever the DST or timezone currently is. If they go into DST, they’ll go to work at 8:30, when they exit from DST, they’ll go to work at 8:30. If the country decides to move to another timezone, they’ll go to work at 8:30 eveyday

    Mar 9, 2017 at 16:54