4

This is not a post about technology per se, rather a post about the appropriate algorithm. I want my users to be able to schedule an event on my application to occur at a specific time (which they will see displayed in their time zone on my site) every week.

Say a user in New York schedules the event to occur at 8pm EST. I would like the event to occur for this user at 8pm EST every week for the entire year, regardless of daylight savings time.

Currently I'm storing the time value in UTC in my database, but UTC does not change based on the time of year. It seems that some timezones do have a concept of daylight savings and some dont, which means that if I were to do any timezone translation processing on the fly (either before any queries that lookup the date in order to schedule the event, or to display the scheduled time on the site) I would have to see if the user's timezone supports daylight savings and if the target timestamp falls within a daylight savings period.

How do people typically solve this type of problem? In other words, how should I store a logical time in my database, display it properly, use it for scheduling a task properly regardless of daylight savings time, for all user timezones, in the simplest way possible?

Josh Nankin
  • 2,518
  • 4
  • 28
  • 45

3 Answers3

1

I will make one assumption, you meant "...in Eastern Time every week for the entire year". When you say EST, you are specifically referring to Eastern Standard Time. When DST is applicable, it is known as Eastern Daylight Time (EDT).

Also, abbreviations are not a good way to identify time zones. How I would I know you meant EST in the United States (UTC-5) and not EST in Australia (UTC+10)? Abbreviations are ambiguous. You can see a fairly comprehensive list here.

The first thing to do is to decide how you want to identify the user's time zone. There are two databases in common use:

The Microsoft Time Zone Database

PROs

  • Built in to Windows operating system.
  • Updates deployed automatically through Windows Update.
  • Easy to consume from Win32 or .Net Framework.

CONs

  • Maintained by Microsoft instead of a standards body or community.
  • Zones tend to be very broad instead of refined.
  • Not good with historical time zone changes.
  • Interoperability with non-Microsoft servers can be painful.
  • Updated less frequently.

The IANA/Olson Time Zone Database

PROs

  • Widely implemented on Linux, Mac, Java, PHP, and many other platforms.
  • Libraries are available for JavaScript and for Windows/.Net.
  • Refined, distinct time zones named from an exemplar city.
  • Contains historical data for time zone changes.
  • Referenced in many RFCs and other standards.
  • Community maintained, recently backed by IANA.
  • Frequent updates, several times a year.

CONs

  • Not usually maintained automatically, although some implementations may do so.
  • There are so many zones, it can be difficult to present a simple drop-down list to your users. Map-based timezone pickers, such as this one, are needed for a good user experience.

Now that you have identified which time zone your user is in - let's get to the heart of your original question. How should you deal with a recurring event that is at the same local time without regard to DST changes?

You actually have two different concerns, persistence and execution.

For persistence (and transport, display, etc.) you need to store a combined local time and time zone. For example, 8:00 PM in the America/New_York IANA zone. If possible in your framework, store this time without a date component. Don't convert it to UTC or try to adjust it for DST. You are simply capturing the users intent in the way they have expressed it to you.

For execution, you need to fire your recurring job at a specific scheduled time. The server your job is running on might be in a different time zone entirely. What you need is a series of UTC DateTime values, so you can set a task scheduler to fire at specific moments in instantaneous time. You might also use a local-time-plus-utc-offset for this, such as a DateTimeOffset in .Net. That would have the advantage of seeing 8:00PM on every value, even if the offset was switching between -4 and -5. See DateTime vs DateTimeOffset.

To align these two concepts, you need some code that will evaluate the local time and compute the execution timestamp. You could just set up the next scheduled job as each job runs, or you could do this periodically and project event times for some future X number of events. That's up to you. If you need to put future event dates on a calendar - then you certainly need the latter approach.

Community
  • 1
  • 1
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Also - I see from your profile that you have some PHP background. PHP has a native IANA/Olson implementation. Reference: http://php.net/manual/en/timezones.php – Matt Johnson-Pint Mar 08 '13 at 14:55
0

Perhaps you can use any of the publicly available time zone APIs. Eg. https://developers.google.com/maps/documentation/timezone/ .

ElKamina
  • 7,747
  • 28
  • 43
0

I would convert into UTC as soon as possible and out of UTC as late as possible, because when countries switch out of DST at the end of the summer they put the clocks back, and there are two hours in the day with the same time - so DST times cannot uniquely describe all times.

mcdowella
  • 19,301
  • 2
  • 19
  • 25