Flawed Approach
Closed this issue · 9 comments
Nice attempt, but you seem to be under the impression that you can accurately determine the IANA/Olson/PHP time zone from just the current offset and whether or not DST is currently in effect. That is not sufficient data to accurately resolve the zone.
The main reason is that DST starts and stops at different times all over the world. There are many time zones that are indistinguishable otherwise. For example, Asia/Jerusalem
and Asia/Beirut
both use +02:00 for their standard time offset and +03:00 for their daylight time offset, but they start and end DST at different times.
You may want to look at jsTimeZoneDetect. You will see there that it tests several specific points in time to make the determination. But even that is not perfect, because almost all modern browsers are affected by ECMAScript 15.9.1.18 as I describe here. They also fail for the example I gave above. See this issue and this related issue, and other open issues on that site.
I'm sorry, but there is no magic bullet for completely accurate time zone detection in JavaScript. It's coming soon with the new ECMAScript Internationalization API, as I described here, but the current implementations are buggy and don't exist everywhere.
Again, I appreciate your efforts, but your project is not doing what you set out to accomplish. It can give a false sense of security to those that don't understand the intricacies of time zones.
Indeed detecting users timezone is a complex and complicated problem. This script will work in most of situations, and if in some really rare cases it detects the users timezone incorrectly, the web application should make it easy for the users to change his timezone from a dropdown, as I mentioned in the README file.
...However, it's recommended to make it possible for your users to change their timezones manually (for example on their profile/settings page).
Do you have tests to prove that it will work in "most" situations?
Do you have tests to prove it will not?
Just trying a few things that are extremely common and finding failures. Testing on Windows 8 with IE10.
Computer Time Zone Setting Expected Actual Result
------------------------------------------------------------------------------------------------
(UTC-05:00) Eastern Time (US & Canada) America/New_York US/Eastern Acceptable
(UTC-06:00) Central Time (US & Canada) America/Chicago US/Central Acceptable
(UTC-07:00) Mountain Time (US & Canada) America/Denver America/Chihuahua Fail
(UTC-07:00) Arizona America/Phoenix US/Arizona Acceptable
(UTC-08:00) Pacific Time (US & Canada) America/Los_Angeles America/Los_Angeles Pass
(UTC-09:00) Alaska America/Anchorage US/Alaska Acceptable
(UTC-10:00) Hawaii Pacific/Honolulu Pacific/Honolulu Pass
(UTC-03:00) Brasilia America/Sao_Paulo America/Sao_Paulo Pass
(UTC) Coordinated Universal Time UTC Africa/Casablanca Fail
(UTC) Dublin, Edinburgh, Lisbon, London Europe/London Europe/London Pass
(UTC+02:00) Jerusalem Asia/Jerusalem Europe/Athens Fail
(UTC+02:00) Harare, Pretoria Africa/Johannesburg Africa/Cairo Fail
(UTC+01:00) Brussels, Copenhagen, Madrid, Paris Europe/Paris Europe/Amsterdam Acceptable
(UTC+04:00) Moscow, St. Petersburg, Volgograd Europe/Moscow Europe/Volgograd Acceptable
(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi Asia/Kolkata Asia/Calcutta Acceptable
(UTC+08:00) Perth Australia/Perth Asia/Hong_Kong Fail
(UTC+09:00) Osaka, Sapporo, Tokyo Asia/Tokyo Asia/Irkutsk Fail
The ones I mark as "Acceptable" are mostly because they are link aliases. PHP (and others) frown on their usage, as they are their for backwards compatibility only. See the big red box on this page
Again, I am just trying to be helpful. Don't think for a second that I don't appreciate the work you put in to this. It's just not the right approach to solving this problem.
Also, I didn't run through every time zone. Just a handful of them. Also, since your are testing against "now", you will get different results depending the date you test. I can't just change my computer's clock to test, because you are also assuming "now" in your PHP code.
Just focusing on one failure to illustrate. US Mountain Time should resolve to America/Denver
, but running it today (Oct 19, 2013) your library detects America/Chihuahua
.
As shown here, the DST changes for 2013 in Chihuahua, Mexico are on April 7th and October 27th.
As shown here, the DST changes for 2013 in Denver, Colorado, USA are on March 10th and November 3rd.
Therefore, even without considering historical differences, these are not the same time zones. Your library simply sees that they are both today in DST and have -07:00 offset, so it thinks they are the same and just picks the first one it encounters in your list.
Thanks for sharing your test list. Really appreciate your effort! You are true, we can't detect exactly the users timezone based only on the current offset and dst. My primary goal with this script was to detect a (probably) timezone for a user, but if it's not correct they should be able to update it anytime.
Will dive in the problem, to see how the script can be improved (even if it can not be made perfect) in near future, and keep you posted here about it.
No problem. Glad to help!
jsTimeZoneDetect is just about as good as it can get right now.
Things won't get any better until the ECMAScript Internationalization API is supported in all browsers and has it's bugs fixed. You can try it out today in Chrome or Opera:
Intl.DateTimeFormat().resolvedOptions().timeZone
But there are still some bugs in the current versions. See the one I wrote up for example.