This is a HARD question. In fact, it is so complicated that the SQL standard and most of the main databases there have no idea in their implementation.
Converting all datetimes to UTC makes it easy to compare between records, but it discards information about the time zone, which means that you cannot perform calculations with them (for example, add 8 months to the stored date) and not get them in the time zone in which they were kept inside. Thus, the naive approach is absent.
Saving the time zone offset from UTC in addition to the timestamp (for example, a timestamp with a time zone in postgres) will seem sufficient, but different time intervals can have the same offset at one time in a year, and another after 6 months from for DST. For example, you could have New York and Chile as in UTC-4 now (August), but after November 4, New York will be UTC-5, and Chile (after September 2) will be UTC-3. Thus, saving only the offset will not allow you to make accurate calculations. Like the naive approach above, it also discards information.
What if you instead save the timezone identifier (e.g. America / Santiago) with a timestamp? This will allow you to distinguish between Chilean time and date and time in New York. But this is still not enough. If you keep the expiration date, say that at midnight 6 months in the future, and the DST rules change (as, unfortunately, politicians like to do), your timestamp will be incorrect and the expiration may occur at 11:00 or 1 hour instead. Which may or may not be a big problem for your application. Thus, the use of a timestamp also excludes information.
It seems that in order to really be accurate, you need to save the local time (for example, using a timestamp type other than the time zone) with the time zone identifier. To support faster comparisons, you can cache its version of utc until the db time zone you are using is updated, and then update the cached value if it has changed. Thus, it will be 2 naive types of timestamps plus the timezone identifier and some kind of external cron job that checks to see if the db time interval has changed and starts the corresponding update requests for the cached timestamp.
Is this the exact solution? Or am I still missing something? Can this be done better?
I'm interested in solutions for MySQL, SQL Server, Oracle, PostgreSQL and other DBMSs that handle TIMESTAMP WITH TIME ZONE.
timezone sql oracle mysql sql-server
Eloff
source share