Daylight saving time and time zone best practices

462,257

Solution 1

Summary of answers and other data: (please add yours)

Do:

  • Whenever you are referring to an exact moment in time, persist the time according to a unified standard that is not affected by daylight savings. (GMT and UTC are equivalent with this regard, but it is preferred to use the term UTC. Notice that UTC is also known as Zulu or Z time.)
  • If instead you choose to persist a (past) time using a local time value, include the local time offset for this particular time from UTC (this offset may change throughout the year), such that the timestamp can later be interpreted unambiguously.
  • In some cases, you may need to store both the UTC time and the equivalent local time. Often this is done with two separate fields, but some platforms support a datetimeoffset type that can store both in a single field.
  • When storing timestamps as a numeric value, use Unix time - which is the number of whole seconds since 1970-01-01T00:00:00Z (excluding leap seconds). If you require higher precision, use milliseconds instead. This value should always be based on UTC, without any time zone adjustment.
  • If you might later need to modify the timestamp, include the original time zone ID so you can determine if the offset may have changed from the original value recorded.
  • When scheduling future events, usually local time is preferred instead of UTC, as it is common for the offset to change. See answer, and blog post.
  • When storing whole dates, such as birthdays and anniversaries, do not convert to UTC or any other time zone.
    • When possible, store in a date-only data type that does not include a time of day.
    • If such a type is not available, be sure to always ignore the time-of-day when interpreting the value. If you cannot be assured that the time-of-day will be ignored, choose 12:00 Noon, rather than 00:00 Midnight as a more safe representative time on that day.
  • Remember that time zone offsets are not always an integer number of hours (for example, Indian Standard Time is UTC+05:30, and Nepal uses UTC+05:45).
  • If using Java, use java.time for Java 8 and later.
  • Much of that java.time functionality is back-ported to Java 6 & 7 in the ThreeTen-Backport library.
  • Further adapted for early Android (< 26) in the ThreeTenABP library.
  • These projects officially supplant the venerable Joda-Time, now in maintenance-mode. Joda-Time, ThreeTen-Backport, ThreeTen-Extra, java.time classes, and JSR 310 are led by the same man, Stephen Colebourne.
  • If using .NET, consider using Noda Time.
  • If using .NET without Noda Time, consider that DateTimeOffset is often a better choice than DateTime.
  • If using Perl, use DateTime.
  • If using Python 3.9 or later, use the built-in zoneinfo for working with time zones. Otherwise, use dateutil or arrow. The older pytz library can generally be avoided.
  • If using JavaScript, avoid using the older moment.js or moment-timezone libraries, as they are no longer actively maintained. See the Moment.js project status for more details. Instead, consider Luxon, date-fns, day.js, or js-joda.
  • If using PHP > 5.2, use the native time zones conversions provided by DateTime, and DateTimeZone classes. Be careful when using DateTimeZone::listAbbreviations() - see answer. To keep PHP with up to date Olson data, install periodically the timezonedb PECL package; see answer.
  • If using C++, be sure to use a library that uses the properly implements the IANA timezone database. These include cctz, ICU, and Howard Hinnant's "tz" library. In C++20 the latter is adopted into the standard <chrono> library.
    • Do not use Boost for time zone conversions. While its API claims to support standard IANA (aka "zoneinfo") identifiers, it crudely maps them to POSIX-style data, without considering the rich history of changes each zone may have had. (Also, the file has fallen out of maintenance.)
  • If using Rust, use chrono.
  • Most business rules use civil time, rather than UTC or GMT. Therefore, plan to convert UTC timestamps to a local time zone before applying application logic.
  • Remember that time zones and offsets are not fixed and may change. For instance, historically US and UK used the same dates to 'spring forward' and 'fall back'. However, in 2007 the US changed the dates that the clocks get changed on. This now means that for 48 weeks of the year the difference between London time and New York time is 5 hours and for 4 weeks (3 in the spring, 1 in the autumn) it is 4 hours. Be aware of items like this in any calculations that involve multiple zones.
  • Consider the type of time (actual event time, broadcast time, relative time, historical time, recurring time) what elements (timestamp, time zone offset and time zone name) you need to store for correct retrieval - see "Types of Time" in this answer.
  • Keep your OS, database and application tzdata files in sync, between themselves and the rest of the world.
  • On servers, set hardware clocks and OS clocks to UTC rather than a local time zone.
  • Regardless of the previous bullet point, server-side code, including web sites, should never expect the local time zone of the server to be anything in particular. see answer.
  • Prefer working with time zones on a case-by-case basis in your application code, rather than globally through config file settings or defaults.
  • Use NTP services on all servers.
  • If using FAT32, remember that timestamps are stored in local time, not UTC.
  • When dealing with recurring events (weekly TV show, for example), remember that the time changes with DST and will be different across time zones.
  • Always query date-time values as lower-bound inclusive, upper-bound exclusive (>=, <).

Don't:

  • Do not confuse a "time zone", such as America/New_York with a "time zone offset", such as -05:00. They are two different things. See the timezone tag wiki.
  • Do not use JavaScript's Date object to perform date and time calculations in older web browsers, as ECMAScript 5.1 and lower has a design flaw that may use daylight saving time incorrectly. (This was fixed in ECMAScript 6 / 2015).
  • Never trust the client's clock. It may very well be incorrect.
  • Don't tell people to "always use UTC everywhere". This widespread advice is shortsighted of several valid scenarios that are described earlier in this document. Instead, use the appropriate time reference for the data you are working with. (Timestamping can use UTC, but future time scheduling and date-only values should not.)

Testing:

  • When testing, make sure you test countries in the Western, Eastern, Northern and Southern hemispheres (in fact in each quarter of the globe, so 4 regions), with both DST in progress and not (gives 8), and a country that does not use DST (another 4 to cover all regions, making 12 in total).
  • Test transition of DST, i.e. when you are currently in summer time, select a time value from winter.
  • Test boundary cases, such as a timezone that is UTC+12, with DST, making the local time UTC+13 in summer and even places that are UTC+13 in winter
  • Test all third-party libraries and applications and make sure they handle time zone data correctly.
  • Test half-hour time zones, at least.

Reference:

Other:

  • Lobby your representative to end the abomination that is DST. We can always hope...
  • Lobby for Earth Standard Time

Solution 2

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.

Solution 3

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).

Solution 4

Make clear architectural separation of concerns - to know exactly which tier interacts with users, and has to change date-time for/from canonical representation (UTC). Non-UTC date-time is presentation (follows users local timezone), UTC time is model (remains unique for back-end and mid tiers).

Also, decide what's your actual audience, what you don't have to serve and where do you draw the line. Don't touch exotic calendars unless you actually have important customers there and then consider separate user-facing server(s) just for that region.

If you can acquire and maintain user's location, use location for systematic date-time conversion (say .NET culture or a SQL table) but provide a way for end-user to choose overrides if date-time is critical for your users.

If there are historical audit obligations involved (like telling exactly when Jo in AZ paid a bill 2 yrs ago in September) then keep both UTC and local time for the record (your conversion tables will change in a course of time).

Define the time referential time zone for data that comes in bulk - like files, web services etc. Say East Coast company has data center in CA - you need to ask and know what they use as a standard instead of assuming one or the other.

Don't trust time-zone offsets embedded in textual representation of the date-time and don't accept to parse and follow them. Instead always request that time zone and/or reference zone have to be explicitly defined. You can easily receive time with PST offset but the time is actually EST since that's the client's reference time and records were just exported at a server which is in PST.

Solution 5

You need to know about the Olson tz database, which is available from ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/. It is updated multiple times per year to deal with the often last-minute changes in when (and whether) to switch between winter and summer (standard and daylight saving) time in different countries around the world. In 2009, the last release was 2009s; in 2010, it was 2010n; in 2011, it was 2011n; at the end of May 2012, the release was 2012c. Note that there is a set of code to manage the data and the actual time zone data itself, in two separate archives (tzcode20xxy.tar.gz and tzdata20xxy.tar.gz). Both code and data are in the public domain.

This is the source of time zone names such as America/Los_Angeles (and synonyms such as US/Pacific).

If you need to keep track of different zones, then you need the Olson database. As others have advised, you also want to store the data in a fixed format — UTC is normally the one chosen — along with a record of the time zone in which the data was generated. You may want to distinguish between the offset from UTC at the time and the time zone name; that can make a difference later. Also, knowing that it is currently 2010-03-28T23:47:00-07:00 (US/Pacific) may or may not help you with interpreting the value 2010-11-15T12:30 — which is presumably specified in PST (Pacific Standard Time) rather than PDT (Pacific Daylight Saving Time).

The standard C library interfaces are not dreadfully helpful with this sort of stuff.


The Olson data has moved, in part because A D Olson will be retiring soon, and in part because there was a (now dismissed) law suit against the maintainers for copyright infringement. The time zone database is now managed under the auspices of IANA, the Internet Assigned Numbers Authority, and there's a link on the front page to 'Time Zone Database'. The discussion mailing list is now [email protected]; the announcement list is [email protected].

Share:
462,257
Oded
Author by

Oded

Former Stack Overflow employee. I am a C# ASP.NET developer, with a long professional history of work with web and Microsoft technologies. I am passionate about writing usable and secure software and am constantly learning. Blog at http://OdedCoster.com/blog. I have written a blog series about getting good answers on StackOverflow.

Updated on January 29, 2022

Comments

  • Oded
    Oded over 2 years

    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.

    • Oded
      Oded almost 12 years
      @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.
    • abatishchev
      abatishchev almost 12 years
      @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.
    • Chris Johnson
      Chris Johnson over 11 years
      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/…
    • Kenny Evitt
      Kenny Evitt about 11 years
      @JoshStodola -- Jon Skeet's 'answer'.
    • arviman
      arviman over 10 years
      @KennyEvitt - NodaTime is a port of the Java library "JodaTime", although i know you were joking about Skeet's answer.
    • ono2012
      ono2012 about 8 years
      @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
    • Chris Marisic
      Chris Marisic almost 8 years
      There are several confusingly duplicative time zone ids such as “US Eastern Standard Time” vs “Eastern Standard Time” , you should read here to learn more: stackoverflow.com/a/15448800/37055
    • mc0e
      mc0e about 7 years
      Actually GMT and UTC are not quite equivalent. This is because GMT is defined in terms of the rotation of the earth, and the speed of that rotation varies in an unpredictable manner. Decisions are made as to when to insert leap-seconds into UTC to keep it in line with the solar day (which GMT is based on), so that at any given time the two are the same to within 0.9 seconds.
    • RBT
      RBT over 2 years
  • Yuval Adam
    Yuval Adam about 14 years
    To paraphrase Linus Torvalds :)
  • stoodfarback
    stoodfarback about 14 years
    Using GMT doesn't really solve the problem, you still need to figure out what is the right delta to apply, and this is where all the complexity lies. The delta can be complex to determine in systems that are used by users in different regions (with different daylight saving switch schedules) or in systems showing historical/future data.
  • Yuval Adam
    Yuval Adam about 14 years
    @ckarrs - figuring out the time zone or the DST policy is NOT the job of an application. The OS should handle that - transparent to the application. In any case even if the OS has a wrong time/time zone, it factors out in the global perspective of the application.
  • stoodfarback
    stoodfarback about 14 years
    That's true if all the application needs to do is to display the current local time. But if we have for example a server in Australia that needs to display the date/time for a transaction in Canada on April 2 2006 (This was the last year before the daylight saving switching rules changed in Canada) - do you have an OS call that can do DateTime("2006/04/02 14:35Z").ToLocalTime().WithDaylightSavingRules("Canada",2006‌​) ?
  • Michael Madsen
    Michael Madsen about 14 years
    Yes, there is such an OS call in Windows - SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
  • Aaronaught
    Aaronaught about 14 years
    I wish it were always this easy... sometimes, you need to aggregate (denormalize) data occurring on a specific day for performance reasons, and the aggregates must be in local time, otherwise customers start calling in and asking why your web site is wrong.
  • BalusC
    BalusC about 14 years
    Javascript runs at the client machine, not at the server machine. Javascript's base datetime is the client's datetime, not the server's datetime.
  • Josh Kelley
    Josh Kelley about 14 years
    The Olson database contains historical data as well, which makes it particularly useful for handling DST. E.g., it knows that a UTC value corresponding to March 31, 2000 in the U.S. is not in DST, but a UTC value corresponding to March 31, 2008 in the U.S. is.
  • Josh Kelley
    Josh Kelley about 14 years
    The Unicode Consortium maintains a mapping between Olson tome zone IDs and Windows time zone IDs: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
  • Daniel Noworyta
    Daniel Noworyta about 14 years
    Hi BalusC. I understand this (from my original post: "javacode script on the client that built up the date..."). My issue was that certain client machine processed DST one way, and some others another way. Therefore I moved all of that processing server-side to prevent the browser weirdness
  • BillThor
    BillThor almost 14 years
    Your database idea has already been implemented as the Olson Database. While daylight savings time does create an overlap specifying the daylight specific timezone can help resolve the issue. 2:15 EST and 2:15 EDT are different times. As noted in other posts specifying the offset also resolves the ambiguity.
  • Joe Phillips
    Joe Phillips almost 14 years
    My girlfriend, a nurse, works nights and they have to write the timezone during the DST switchover. For instance, 2AM CST vs 2AM CDT
  • Jared Hales
    Jared Hales almost 14 years
    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.
  • Oded
    Oded over 13 years
    @Anonymous Type - noda-time is a work in progress, started by Jon Skeet.
  • tchrist
    tchrist over 13 years
    “Persist” is not a transitive verb. One cannot *persist anything.
  • Chris
    Chris over 13 years
    +1 for the Trivia. Keeping the content interesting makes this task more enjoyable, which may lead to increased productivity :)
  • Span
    Span almost 13 years
    Updated link for the Unicode Consortium's page: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
  • shealtiel
    shealtiel over 12 years
    Where can one found information about parsing the Olson files? I want to compile it into a db table, but can't figure out how should I read the files
  • Jonathan Leffler
    Jonathan Leffler over 12 years
    @gidireich: the main information is found with the data, and it is not easy to understand. The main documentation for it is in the zic.8 man page (or zic.8.txt). You'll need the tzcode2011i.tar.gz file rather than, or as well as, the tzdata2011i.tar.gz file to get this information.
  • Alix Axel
    Alix Axel over 12 years
    Very good answer bluesmoon, thanks.
  • Peter Ajtai
    Peter Ajtai about 12 years
    @tchrist Maybe if you're persistent you can.
  • nogridbag
    nogridbag about 12 years
    The local time offset will allow you to recreate the original "wall time" of the event. If you do not store this additional field, this data is lost.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    Yes, except UTC and GMT offsets are inverse. For example UTC-0700 is the same as GMT+0700. Really, everything digital should be using UTC these days.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    Local time (the server time) can be ambiguous during "fall-back" style daylight savings transitions. It's not reliable to use as you described. There may be more than one UTC time that the server's local time could be representing.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    The problem here is that civil time (aka calendar time) does not properly represent a single moment in time. If you take the seconds-from-epoch approach, are you really going to account for every moment that was skipped over or rewound for daylight savings transitions? Probably not. Epoch basis only works against UTC or some other fixed, instantaneous-time reference.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    Great point. NTFS doesn't have this problem, but some people still use FAT32 - especially on USB keys.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    The big problem with keeping your own database is keeping it updated. Olson and Windows are maintained for you. I've had more than one case of having bad DST transitions because tables were out of date. Ripping them out entirely and relying on a framework or OS level database is much more reliable.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    For display, the offset is perfect. If you want to make changes, the offset is still not enough. You have to also know the time zone because the new value may require a different offset.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    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.
  • Matt Johnson-Pint
    Matt Johnson-Pint over 11 years
    -1 When it comes to dates and times - eliminate always from your vocabulary. Often, yes, but not always. Sometimes it is unlawful or against policy to store anything but a local time - in which case you can store a local time + offset (such as a DateTimeOffset) instead. Other times, you may really want to store a pure local calendar time because you mean "local to you wherever you might be".
  • bluesmoon
    bluesmoon over 11 years
    Thanks for the comments @MattJohnson. I did not know about legal issues related to data storage, but I guess that falls under the larger umbrella of l10n. TimeZone abbreviations are ambiguous, and arbitrary. There's no international standard for them, however full names are better (eg: Asia/Calcutta or Australia/Sydney).
  • Reto Höhener
    Reto Höhener about 11 years
    @Matt: are you sure about UTC and GMT offsets being inverse? where can I read up on that?
  • Matt Johnson-Pint
    Matt Johnson-Pint about 11 years
    Actually, I think I was incorrect before. GMT and UTC aren't inverted themselves. It's that there are implementations that show them in inverse, such as the IANA/Olson/TZDB database. See here. Another area you see offsets in inverse is in javascript's getTimezoneOffset() function.
  • Alix Axel
    Alix Axel about 11 years
    @MattJohnson: Those are hacks and should be abolished.
  • eselk
    eselk about 11 years
    Keep in mind converting future dates (even just tomorrow) to UTC you always lose something. For example, you used some known offset to make that conversion, but since the date is in the future, there is always a chance the group that sets those rules will change those rules. Also, it is virtually impossible to convert some future dates to UTC because the daylight savings times are not known until that year (some countries set the dates every year, not 10+ years ahead or based on any set rules).
  • eselk
    eselk about 11 years
    Awesome info, just wish I could find details on most of the topics covered here. For example, keeping DB/App in sync, does this mean you are doing a bulk update on the db when rules change? Or is that what the extra timestamp avoids, but then that means you have to keep a log of various rule changes and have functions to convert using any of those rules over time?
  • bluesmoon
    bluesmoon about 11 years
    @eselk all rule changes have a timestamp when they go into effect, and the tz-info file typically includes these dates so that the system knows to use the old rules for dates prior to this and the new rules for dates after.
  • sayap
    sayap about 11 years
    Local time is perfectly fine if the server is located in a sane time zone, i.e. one that doesn't do DST.
  • Alex
    Alex over 10 years
    Yes, this is common: when you compute a (civil) daily average, you have to cope with days of 23, 24, or 25 hours. As a consequence, when you compute add 1 day it is not add 24 hours! Second, don't try to build your own timezone code ; only use systems API. And don't forget to update each deployed system in order to get the up-to-date timezone database.
  • Alex
    Alex over 10 years
    Do not create your own database: always rely on system's API!
  • supercat
    supercat over 10 years
    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
    supercat over 10 years
    ...knowing whether they reflect an accurate local time or global time may be important in determining how to correct them.
  • saravana_pc
    saravana_pc over 10 years
    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?
  • caradrye
    caradrye over 10 years
    This is not a solution to the problem presented.
  • Yaron U.
    Yaron U. about 10 years
    Regarding Israel - this is half true. Though the time for the DST change is not a specific date in the Julian calendar - there is a rule based on the Hebrew calendar (there was a change in 2014). Anyway, the general idea is correct - this things might and do change once in a while
  • ruffin
    ruffin almost 10 years
    The Netherlands trivia looks legit. ietf.org/rfc/rfc3339.txt section 5.8. Halfway figured someone was pulling our leg.
  • ruffin
    ruffin almost 10 years
    @Me -- I'd like to attribute your quote to you, but I'm having a difficult time displaying Now.
  • mmmmmm
    mmmmmm almost 10 years
    @ChocolateMouse - You need to explain why using that query matters
  • Andriy M
    Andriy M almost 10 years
    @Mark: Doesn't the linked article provide enough explanation?
  • mmmmmm
    mmmmmm almost 10 years
    @AndriyM It might but the information should be here - at least an overview crediting the original source
  • Andriy M
    Andriy M almost 10 years
    @Mark: Perhaps you are right, it's just that there are many other similar bullet points in this answer: a simple "do/don't" statement with a link to a resource with more info. The last added item doesn't really stand out for me in that regard.
  • RobG
    RobG over 9 years
    @Joon—and there are bugs in javascript implementations that you can't detect or allow for. So yes, don't ever use client–side ECMAScript date calculations for things that matter (though you can do a pretty good job otherwise).
  • Matt Johnson-Pint
    Matt Johnson-Pint almost 9 years
    This doesn't work when you consider DST changes. getTimezoneOffset returns the offset for the date and time you call it on. That offset can change when a time zone transitions in or out of daylight saving time. See "time zone != offset" in the timezone tag wiki.
  • prusswan
    prusswan about 8 years
    @eselk unless the future dates are derived from UTC. no loss going from UTC -> UTC
  • Suncat2000
    Suncat2000 almost 8 years
    GMT and UTC are not equivalent. GMT is subject to Daylight Saving Time: it's then called British Summer Time. UTC times are contiguous and are free of gaps and overlaps.
  • user253751
    user253751 almost 8 years
    @MattJohnson Hence the "business rules" part. If the rules say something happens at 2:30 in the morning (or whichever time), it will happen twice on one day a year and never on one day a year. That's what the customer expects to happen if they don't clarify the rule.
  • mmmmmm
    mmmmmm over 7 years
    @Suncat no GMT is not subject to Daylight Savings - The UK is subject to daylight savings and in the summer is on BST but that does not change GMT
  • Mangu Singh Rajpurohit
    Mangu Singh Rajpurohit over 7 years
    Great Answer @MattJohnson, Would have given you +1000, if allowed. Thanks for clear explanation.
  • Suncat2000
    Suncat2000 over 7 years
    @Mark Agreed, for casual use, and as a time zone offset, there is no significant difference. But where I disagree is that if you are using it to represent an actual time zone, the local time changes during the summer. You can say exactly the same thing about EST in the US, since we're being pedantic. I'm merely pointing out UTC and GMT are not equivalent and it may be inaccurate to treat them the same, depending on your use.
  • mmmmmm
    mmmmmm over 7 years
    No GMT is not a timezone -which is why the answer says America/New_York not EST.
  • Gianluca Ghettini
    Gianluca Ghettini about 7 years
    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
  • Ad Infinitum
    Ad Infinitum about 7 years
    Another example for governments to do weird things: timeanddate.com/news/time/turkey-scraps-dst-2016.html
  • Alex
    Alex almost 7 years
    If you want to store an alarm like "do something at 10:00", you cannot store it in UTC, because of DST shifts. You must store it relative to the local time.
  • DavidWalley
    DavidWalley almost 7 years
    Also, AST = Atlantic Standard Time. As for the 'best advice', it is okay as a starting point, but you need to read the rest of this page, and say a little prayer, and you might get it right for a while.
  • DavidWalley
    DavidWalley almost 7 years
    This is good advice as a starting point, but it totally depends on the application. This might be fine for a friendly website, but if there is any legal/jurisdictional/financial aspect to your application that someone might sue over (I have worked on several), then this is an over-simplification because there are different kinds of 'time', as noted elsewhere on this page.
  • Turgs
    Turgs over 6 years
    The answer on this Rails question suggests a workable technique for storing event dates in the future taking this answer above into account.
  • Steve Summit
    Steve Summit over 6 years
    Keeping internal timestamps in civil time can be very tricky. Keeping it as seconds since an epoch is trickier still, I'd say downright perilous. I'm sure there are people doing it, and it might be possible to get it to work properly most of the time if you're super careful, but it can't be considered a best practice or a general recommendation.
  • Vishnu Haridas
    Vishnu Haridas over 4 years
    So if we live in a Utopia where timezone and DST rules NEVER change at all, we can save future events in UTC, correct?
  • Amit Meena
    Amit Meena almost 3 years
    This answer/wiki is one of the most concise, clear, and crisp documentation on time and timezones on the web. Kudos to all of the contributors :)
  • Ruslan Stelmachenko
    Ruslan Stelmachenko over 2 years
    Disagree with "When storing a timezone, you need the name, timestamp and the offset.". You need just an ID from Time Zone Database. UTC time + this ID could unambiguously be converted to exact local time of a stored event, no matter what rules were changed by a government after this event, because Time Zone Database contains historical data for each timezone with exact rules and timestamps of when and how offsets/etc were changed.
  • bluesmoon
    bluesmoon over 2 years
    That's just database normalization (storing IDs instead of denormalized tuples).