Why You Should Use Timezone Offsets Not Timezone Names
tantek.com
tantek.com
Storing UTC offsets means that any future political changes will result in the wrong local times for users.
If you are referring to an instant in time, then just using UTC is reasonable. If you are referring to a past event and both the local time and precise instant are relevant, then the local time with a timezone offset is reasonable. If you are scheduling events on a calendar, however, like "8 AM every monday for the next four weeks", then yes, you need to store the abstract time zone name so that the calendar program can translate each instance of that schedule to the appropriate instant.
[0] https://en.wikipedia.org/wiki/Tz_database
See: Example zone and rule lines
The ones that have a tiny map that you have to click on are also pretty bad.
Besides, for your case there are easier methods, like Googling "current time in San Marcos, TX" (which Google will actually tell you the time and time zone without you needing to click on a results page; if you feel the need to, the first result has all the info you need as well). Hell, the "world clock" app on my phone tells me what I need to know when I enter in that city.
"America/Chicago" is a standard timezone name.
Personally, I (living in SF), use the "PST8PDT" named timezone; it just makes more sense to me than "America/Los Angeles", which is 400+ miles away from me (even though historically we've always had the same time as LA... as far as I know).
[0] Yes, there are a few places in the continental US that don't follow the "normal" 4 timezones and their DST schedules, so there are exceptions; specifically calling out those cities/locales is necessary, at least in those cases.
http://google.com/search?q=Omaha,+NE+timezone
It may be a standard timezone name, but it's not a very user-friendly one.
(And I may be further proving your point if Denver isn't the landmark city, I'm just guessing!)
The one in the Americas is the only one called "Central Time". It may not be the most politically correct name, but it happens to be the only name for it I know of, and it's the only timezone with that exact name worldwide.
* store the appointment date and place as a string "february 23 at 6pm here"; * store the time when the date has been uttered/written in UTC or, better, TAI; * store the place where the date has been uttered/written: "Europe/Rome" or, better, GPS coordinates.
These three pieces allows you to convert the target date to any timezone, even in case the definition of timezones changes.
This three-pieces encoding is very helpful during legal disputes as it allows you to say "On a certain date we agreed on this date in the future. At the time the appointment was supposed to be XXX hours away. The fact that is now only YYY hours away is not our fault but the consequence of country CCC changing to a different time zone." It also works well for other imprecise utterances like "tomorrow".
It's not possible to make a generalized assertion about the correct way to deal with time. If you're building a global distributed database, you probably want all your timestamps in UTC. If you're building a calendar application, not so much.
Some systems also need to record the time the observation was made, introducing a 2nd dimension of time. This becomes important very quickly when trying to design a system with an immutable (append-only) data store.
There are a lot more timezones than there are offsets, and several timezones may have the same offset at a given point in time, but that may not be true every day of the year because they have different rules.
So the robust solution is to make all your datetimes "timezone" aware, not "offset" aware. And yes that means using the Olsen Data and yes that means more complications. But it's the only way to have accuracy for human-oriented datetimes.
Secondly, time units do not have a fixed reference clock. `Second` is clocked by the Universe, `day` is clocked by midnight and year is clocked by New Year. Generally, by `time` we mean "distance in time since last Midnight in one second resolution" and that includes single clock source. By `date` we generally mean "distance in time since last particular arbitrary event in one day resolution", which includes two clock sources (midnight and new year). This gets rather awkward, but both sources get controlled by the "particular arbitrary event", therefore we can handle that. Combining both definitions into "distance in time since arbitrary event in one second resolution" gives us `datetime`, controlled by three clock sources. Thing are bound to get awkward.
Lastly, as others have already pointed out, all this makes definitions of future events in `datetime` pretty much useless, because there is no way to predict how many ticks clock sources will generate, unless you stick with one (e.g. n Universe clocked seconds from NOW (isn't TAI exactly that?)) and deal with fluctuating clock sources in the future.
Neither solution solve inherent problems with multi-clocked `datetime` definition only might make some problems easier to solve by shifting clock tracking to frontend: 2051-09-12 16:23:00 +0300 does not need to keep track of clock sources while 2051-09-12 16:23:00 Europe/Vilnius does.
The whole "Bonus" section is about arbitrary{ty|ness} of "last midnight" - how long ago did it actually happen for this moving target? Should I consider offset from last midnight from time I have actually seen it or when it was supposed to be seen here? Automatic time zone settings attempt to do the latter. And if you want former semantics, well just do not use automagic and add whole new clock source to this mess - "distance in time since last time I personally thought it was midnight".
Also, when presenting times to users, knowing what timezone they're in, helps us display the dates with the correct offsets (without need to change it twice a year).
Timezone codes are useful. They're better in offsets in any way since they contain more data. It's one of those headaches for developers that save headaches to the users.
leap seconds, or the like
What else other than leap seconds are you referring to? Leap seconds are a problem for all time storage since most time parsers consider second 61 invalid [1]. They also only happen about once a year. Google just pretends they don't exist [2].Converting from epoch to the local timezone is supported in pretty much every language. I'm not sure why you think it's such a pain.
[1] https://dev.mysql.com/doc/refman/5.0/en/time-zone-leap-secon...
[2] http://googleblog.blogspot.com/2011/09/time-technology-and-l...
One way of modelling it is as saying that seconds in Unix time all have the same length, that differs by some factor from SI seconds, though that factor changes every time a leap second is introduced.
Another way is to say that seconds don't all have constant length; some seconds have a different length than the rest of the seconds (like those in the hour or day leading up to a leap second, or even just that the one second before the leap second is twice as long as a regular second).
The "or the like" was just a hedge against other possible ways of describing this divergence that I hadn't described in that one quick sentence.
Pretending that leap seconds don't exist is all well and good if you have a completely closed system, but as soon as you try to synchronize with or compare timestamps with UTC, you'll start running into problems.
> Usually when a leap second is almost due, the NTP protocol says a server must indicate this to its clients by setting the “Leap Indicator” (LI) field in its response. [..] Rather than doing this, we applied a patch to our internal NTP servers to not set LI, and tell a small “lie” about the time, modulating this “lie” over a time window w before midnight
That being said, the gist of the post (time normalization) is obviously good. Stored time should always be UTC and converted for display later.
Has anyone figured out a way for me to get the users timezone from their city?
This is apparently an argument against UTC, but I think it's an argument against local time instead - humans comparing times stored in different timezones causes a lot of errors.