Olson timezone id detection is broken on Android
Reported by
clement....@gmail.com,
May 16 2017
|
||||||||
Issue description
Steps to reproduce the problem:
new Intl.DateTimeFormat("en-US", { month: 'short' }).format(new Date(2017, 2, 1))
What is the expected behavior?
It should return 'Mar' for march.
What went wrong?
It returns 'Feb' instead.
Did this work before? N/A
Chrome version: 58.0.3029.83 Channel: stable
OS Version:
Flash Version:
On desktop Chrome it works fine but not on Android chrome.
Strangely
new Intl.DateTimeFormat("en-US", { month: 'short' }).format(new Date(2017, 4, 1))
works ('May'), but
new Intl.DateTimeFormat("en-US", { month: 'short' }).format(new Date(2017, 4, 1))
fails ('Mar' instead of 'Apr')!
,
May 17 2017
Cannot reproduce with Version 58.0.3029.110 (64-bit). Can you update and try reproduce?
,
May 17 2017
I can still reproduce but I should have mentioned that I think it has something to do with my timezone (Sydney, Australia). Can you try to change your timezone and try again?
,
May 18 2017
,
May 18 2017
I'm not so sure they are duplicate. The other one is a display issue. Here the actual value is wrong.
,
May 18 2017
This is not a dup, issue 714301 is specifically about the Date constructor which takes a string. Assigning to jshin@ for triage on the Intl side.
,
May 19 2017
Thanks for the alert. clement.gutel, I cannot reproduce it on Mac Chrome 58.0.3029.81 (64-bit) Does it work if you use 'month: long' or any other format specifiers with 'month' included? I'll also set my timezone to Sydney. BTW, mondrian is funny/buggy. Status: Assigned Merged: issue 71430
,
May 19 2017
The bug is on Android. It works on desktop
,
May 19 2017
To reproduce, set your time zone to Australian eastern standard time zone in your android setting, then open https://jsfiddle.net/dLdntkjk/1/ You would expect Apr, May (as you get on desktop) but I get Mar, May instead.
,
May 19 2017
Not that if I change my timezone to Chicago, the bug disappears. I suspect there must be some utc conversion under the scene causing the issue.
,
May 19 2017
It's pretty bad because Angular 2 is using that API internally to format dates.
,
May 19 2017
> The bug is on Android. It works on desktop
Really?? That's extremely strange.
What do you get from the following?
new Intl.DateTimeFormat("en-US", {year: 'numeric', month: '2-digit', hour: '2-digit', minute: '2-digit', day: '2-digit', timeZoneName: 'long'}).format(new Date(2017, 3, 1))
,
May 19 2017
I get 03/31/2017, 11:00 PM GMT+10:00 And if I replace the month to be instead i get 05/01/2017, 12:00 AM GMT+10:00 Maybe something to do with daylight saving? Jan feb mar april have the bug but not may!
,
May 19 2017
I meant replace the month to be 4 instead of 3
,
May 19 2017
Im pretty sure its a daylight savings bug.
,
May 19 2017
> To reproduce, set your time zone to Australian eastern standard time zone in your android setting, then open https://jsfiddle.net/dLdntkjk/1/ You would expect Apr, May (as you get on desktop) but I get Mar, May instead. With Chrome 60.0.3101.4, I can't reproduce it on Android with the above page. I got 'April' and 'May' with my timezone set to Sydney (UTC+1000). However, I can reproduce it with Chrome 59.0.3071.60 and 58.0.3029.83 . That's strange. On 2017-4-1, Sydney is still in DST while 2017-5-1 it's not. However, I don't see how it can make a difference because Date(2017, 3, 1) should be equivalent to Date(2017, 3, 1, 0, 0, 0) *local* time. I may have messed up the ICU data file for Android (which is smaller than that for desktop chrome) even though I still don't see how it can affect. I'll try to use the Android icu data file with d8 on desktop to see if I can reproduce.
,
May 19 2017
Oh i see. Good find. I cant seem to be able to update my chrome. Is 60 available? The latest version i see in play store is 58.
,
May 19 2017
> I may have messed up the ICU data file for Android (which is smaller than that for desktop chrome) even though I still don't see how it can affect. I'll try to use the Android icu data file with d8 on desktop to see if I can reproduce. Tried that (used the icu data file for Chrome 59 + Android) but no luck.
,
May 22 2017
re comment 18: Playstore has Chrome Beta and Chrome Dev. Currently, Chrome Beta is 59.x and Chrome Dev is 60.x
,
May 22 2017
I see. However I just installed chrome dev and the bug is definitely still there. Are you positive it works with v60?
,
May 22 2017
http://jungshik.github.io/cr/bugs/722821.html is a test page for this bug. Yes, 60.x still has the bug. To reproduce it reliably, I had to reboot after setting my timezone to Australia/Sydney.
,
May 22 2017
toString: Mon May 01 2017 00:00:00 GMT+1000 (AEST) -- Sat Apr 01 2017 00:00:00 GMT+1100 (AEDT) getMonth: 4 -- 3 getUTCMonth: 3 -- 2 shortMonth: May -- Mar Intl datetime with local tz: May 1, 2017, 12:00 AM GMT+10:00 -- Mar 31, 2017, 11:00 PM GMT+10:00 Intl datetime with UTC: Apr 30, 2017, 2:00 PM GMT -- Mar 31, 2017, 1:00 PM GMT
,
May 22 2017
Comment 23 is from Android Chrome 60.0.3101.4. Below is Mac Chrome 58.0.3029.110 : toString: Mon May 01 2017 00:00:00 GMT+1000 (AEST) -- Sat Apr 01 2017 00:00:00 GMT+1100 (AEDT) getMonth: 4 -- 3 getUTCMonth: 3 -- 2 shortMonth: May -- Apr Intl datetime with local tz: May 1, 2017, 12:00 AM Australian Eastern Standard Time -- Apr 1, 2017, 12:00 AM Australian Eastern Daylight Time Intl datetime with UTC: Apr 30, 2017, 2:00 PM GMT -- Mar 31, 2017, 1:00 PM GMT
,
May 22 2017
When tz is set to New Zealand time (DST ended on April 2nd as did in Sydney, but offset is UTC+13 and UTC+12 instead of UTC+11 and UTC+10), Android Chrome does not have this issue. This is getting very interesting.
,
May 22 2017
toString: Mon May 01 2017 00:00:00 GMT+1200 (NZST) -- Sat Apr 01 2017 00:00:00 GMT+1300 (NZDT) getMonth: 4 -- 3 getUTCMonth: 3 -- 2 valueOf/1000/3600: 414876 -- 414155 Delta valueOf/1000/3600: 721 shortMonth: May -- Apr Intl datetime with local tz: May 1, 2017, 12:00 AM New Zealand Standard Time -- Apr 1, 2017, 12:00 AM New Zealand Daylight Time Intl datetime with UTC: Apr 30, 2017, 12:00 PM GMT -- Mar 31, 2017, 11:00 AM GMT
,
May 22 2017
toString: Mon May 01 2017 00:00:00 GMT+1000 (AEST) -- Sat Apr 01 2017 00:00:00 GMT+1100 (AEDT) getMonth: 4 -- 3 getUTCMonth: 3 -- 2 valueOf/1000/3600: 414878 -- 414157 Delta valueOf/1000/3600: 721 shortMonth: May -- Mar Intl datetime with local tz: May 1, 2017, 12:00 AM GMT+10:00 -- Mar 31, 2017, 11:00 PM GMT+10:00 Intl datetime with UTC: Apr 30, 2017, 2:00 PM GMT -- Mar 31, 2017, 1:00 PM GMT
,
May 22 2017
comment 26: Taken from Chrome on Android with the timezone manually set to Pacific/Auckland. comment 27: Taken from Chrome on Android with the timezone manually set to Sydney (Olson timezone is supposed to be Australia/Sydney). Note that in comment 27, 'timezone' field in the 2nd last line is 'GMT+10:00' for both dates instead of Australian Eastern Standard/Daylight Time. OTOH, in comment 26 (Auckland) and comment 24, timezone field is not GMT offset but real long timezone names. This indicates that somehow timezone detection by ICU is off and ICU timezone is set to Etc/GMT-10 (note that the sign has the opposite meaning here. Etc/GMT-10 is *always* 10 hours *ahead* of UTC) instead of "Australia/Sydney" (which is UTC+11 during summer and UTC+10 during winter). This explains what is observed, but I need to figure out why the ICU timezone detection is off apparently only when the Android system timezone is set to Australia/Sydney.
,
May 22 2017
http://bugs.icu-project.org/trac/ticket/13208 is an upstream bug. I'm afraid there's no reliable way to detect the OS timezone and find out the corresponding Olson timezone ID using C/C++ on Android. ICU can be patched to include a very long list of {DST type, standard tz abbr, DST abbr, offset at a fixed point in time, Oslson timezone ID}. It'll be ~ 24kB ( ~ 600 entries). I guess searching through the list for a match won't be an issue. If it's slow, we can optimize it.
,
May 22 2017
https://chromium-review.googlesource.com/511225 can be used to emulate Android on Linux. That CL disables search for tzfile and file link check. With them disabled, v8 on Linux behaves like v8 on Android. $ sudo timedatectl set-timezone Australia/Sydney d8> Intl.DateTimeFormat("en-US").resolvedOptions().timeZone undefined d8> Intl.DateTimeFormat("en-US").format(new Date(2017, 4, 1)) "5/1/2017" d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017, 4, 1)) "5/1/2017, GMT+10:00" d8> new Date(2017,3,1) Sat Apr 01 2017 00:00:00 GMT+1100 (AEDT) d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017,3, 1)) "3/31/2017, GMT+10:00"
,
May 22 2017
With PS #3 in https://chromium-review.googlesource.com/511225 that fixed the AEST/AEDT entry in the mapping table, I got the correct result. d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017,3, 1)) "4/1/2017, Australian Eastern Daylight Time" d8> Intl.DateTimeFormat("en-US").resolvedOptions().timeZone Australia/Sydney The table has to be fixed up for many timezones with abbreviations, but a lot of zones do not have abbreviations. For instance, Asia/Seoul is not in the table. $ sudo timedatectl set-timezone Asia/Seoul $ out/rel/d8 d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017,3, 1)) "4/1/2017, GMT+09:00" d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).resolvedOptions().timeZone undefined <========= should be 'Asia/Seoul'
,
May 22 2017
$ sudo timedatectl set-timezone Asia/Tokyo
d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017,3, 1))
"4/1/2017, Japan Standard Time"
d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).resolvedOptions().timeZone
"Asia/Tokyo"
-----------------
I don't know how Asia/Toyko works while Asia/Seoul does not. Neither of them is in the ICU's hardcoded table for mapping tz abbreviations to Olson tz id.
Need to dig up more.
,
May 22 2017
Because intl
Asia/Taipei has CST for tz abbreviation and it's picked up by v8's special-casing of a few 'grandfathered zone names' (CST, EST, PST, etc) and interpreted as America/Chicago. Perhaps, this is worse than 'undefined'.
$ sudo timedatectl set-timezone Asia/Taipei
d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).format(new Date(2017,3, 1))
"4/1/2017, Central Standard Time"
d8> Intl.DateTimeFormat("en-US", {timeZoneName: "long"}).resolvedOptions().timeZone
"America/Chicago"
,
May 23 2017
Ick... Asia/Shanghai also uses 'CST" for the abbreviation. So, there's no way to distinguish between the two even though historically they may have been different. It looks like I have to file a bug against Android. There should be a better way to detect the timezone (Olson ID) than is currently possible. Obviously, that wouldn't help existing Android devices. For them, we need to add mapping entries (if there's a conflict, we need to pick which one to give a higher priority).
,
May 23 2017
In the long run, it'd be best for Android libc to add a field for Olson timezone ID to 'struct tm'. For that matter, I wonder why glibc or any other C lib implementation hasn't extended 'struct tm' for Olson timezone ID.
-------------
The glibc version of struct tm has additional fields
long tm_gmtoff; /* Seconds east of UTC */
const char *tm_zone; /* Timezone abbreviation */
-----------------
Timezone abbreviation is not as useful.
------------------
In the meantime, we can approach this issue from two sides.
1. If we don't have to worry about v8 outside Chromium, we can use JNI to get the Olson timezone ID with Java API and use it to set the default ICU timezone in the browser process. This is similar to what Chrome OS does except that CrOS does not need JNI.
2. For v8 outside Chromium, quite many new entries have to be added to the mapping table from {tz abbr, standard time offset, DST offset, type of DST} to Olson tzid in ICU.
,
May 23 2017
For the first item in comment 35, there are two places to set the ICU default timezone with a detected Olson tzid ( TimeZone.getDefault().getID() in Java ) - void RendererMainPlatformDelegate::PlatformInitialize() (or in base/i18n/icu_util ). - Android timezone monitor - once a tz change is detected, a new Olson tz id has to be obtained via JNI and be used to set the default ICU timezone. And, the new Olson tz id has to be passed down to render process as is done on Linux. For me (not to forget): http://dev.chromium.org/developers/design-documents/android-jni
,
May 23 2017
https://chromium-review.googlesource.com/c/512282/6 is a CL that is supposed to work (it uses JNI to detect the OS timezone) :-). However, for Android build, linker complains about undefined references even though I think I did all the right things (exporting, dependency config in BUILD.gn, etc). And trybot for other platforms have bug 725644 . To test this out on Android, I'll work around this issue by reverting a small refactoring for now.
,
May 23 2017
> And trybot for other platforms have bug 725644 annotating header-include lines with 'nogncheck' solved the issue. The linker issue on Android is still there, though.
,
May 24 2017
https://chromium-review.googlesource.com/c/512282/ is ready (tested and pending review).
,
Jun 13 2017
Any ETA for release to chrome? This is a huge bug for our Australian users...
,
Jun 19 2017
A patch is ready, but I need to get approval from the reviwer. See the CL in comment 39.
,
Jun 27 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/46cea8687bbbee19b4c48a341c5814ef01dcbb38 commit 46cea8687bbbee19b4c48a341c5814ef01dcbb38 Author: Jungshik Shin <jshin@chromium.org> Date: Tue Jun 27 21:24:42 2017 Detect the OS timezone using JNI ICU timezone detection on Android does not work properly for most timezones. [1] Use JNI to detect the OS timezone and set the ICU default timezone accordingly both on ICU initialization and on timezone change. [1] http://bugs.icu-project.org/trac/ticket/13208 BUG= chromium:722821 TEST=Change the timezone on Android to a few different zones (e.g. Australia/Sydney, Asia/Seoul, Europe/Amstredam). At match what's chosen in Android settings. http: //jungshik.github.io/cr/bugs/722821.html , local tz should Change-Id: I70b98f976c289fb3e717431c9c85bfd66d85b19c Reviewed-on: https://chromium-review.googlesource.com/512282 Reviewed-by: Yaron Friedman <yfriedman@chromium.org> Reviewed-by: Richard Coles <torne@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Jungshik Shin <jshin@chromium.org> Cr-Commit-Position: refs/heads/master@{#482748} [modify] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/base/BUILD.gn [add] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/base/android/java/src/org/chromium/base/TimezoneUtils.java [add] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/base/android/timezone_utils.cc [add] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/base/android/timezone_utils.h [modify] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/base/i18n/icu_util.cc [modify] https://crrev.com/46cea8687bbbee19b4c48a341c5814ef01dcbb38/services/device/time_zone_monitor/time_zone_monitor.cc
,
Jun 27 2017
,
Jun 28 2017
Thanks guys! What can I expect a release in Chrome android (normal version stable)?
,
Jun 28 2017
The fix will be included in Chrome 61. Chrome 59 turned stable on June 6 for Android. So, I expect 61 to turn stable no later than mid September.
,
Jun 28 2017
Clement, thanks a lot for your bug report with details and patience.
,
Jun 28 2017
Great. Thanks for the fix!
,
Jun 28 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/8e58f584d5c7fe4db8f92b41c2f6b9c0135e8013 commit 8e58f584d5c7fe4db8f92b41c2f6b9c0135e8013 Author: Peter Conn <peconn@chromium.org> Date: Wed Jun 28 09:25:17 2017 Revert "Detect the OS timezone using JNI" This reverts commit 46cea8687bbbee19b4c48a341c5814ef01dcbb38. Reason for revert: https://crbug.com/737475 Original change's description: > Detect the OS timezone using JNI > > ICU timezone detection on Android does not work properly for most > timezones. [1] > > Use JNI to detect the OS timezone and set the ICU default timezone > accordingly both on ICU initialization and on timezone change. > > [1] http://bugs.icu-project.org/trac/ticket/13208 > > BUG= chromium:722821 > TEST=Change the timezone on Android to a few different zones (e.g. > Australia/Sydney, Asia/Seoul, Europe/Amstredam). At > match what's chosen in Android settings. > > http: //jungshik.github.io/cr/bugs/722821.html , local tz should > Change-Id: I70b98f976c289fb3e717431c9c85bfd66d85b19c > Reviewed-on: https://chromium-review.googlesource.com/512282 > Reviewed-by: Yaron Friedman <yfriedman@chromium.org> > Reviewed-by: Richard Coles <torne@chromium.org> > Reviewed-by: Mark Mentovai <mark@chromium.org> > Commit-Queue: Jungshik Shin <jshin@chromium.org> > Cr-Commit-Position: refs/heads/master@{#482748} TBR=yfriedman@chromium.org,torne@chromium.org,jshin@chromium.org,mark@chromium.org Change-Id: If098542d9ecfb26ae5181a76e11a8ebd1847e582 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: chromium:722821 Reviewed-on: https://chromium-review.googlesource.com/552157 Reviewed-by: Peter Conn <peconn@chromium.org> Commit-Queue: Peter Conn <peconn@chromium.org> Cr-Commit-Position: refs/heads/master@{#482925} [modify] https://crrev.com/8e58f584d5c7fe4db8f92b41c2f6b9c0135e8013/base/BUILD.gn [delete] https://crrev.com/8af690d4cd89e0e402d08ce8e4f078acf862a317/base/android/java/src/org/chromium/base/TimezoneUtils.java [delete] https://crrev.com/8af690d4cd89e0e402d08ce8e4f078acf862a317/base/android/timezone_utils.cc [delete] https://crrev.com/8af690d4cd89e0e402d08ce8e4f078acf862a317/base/android/timezone_utils.h [modify] https://crrev.com/8e58f584d5c7fe4db8f92b41c2f6b9c0135e8013/base/i18n/icu_util.cc [modify] https://crrev.com/8e58f584d5c7fe4db8f92b41c2f6b9c0135e8013/services/device/time_zone_monitor/time_zone_monitor.cc
,
Jun 29 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/ffb4fbf926444cc3aecd111c98d1521993272593 commit ffb4fbf926444cc3aecd111c98d1521993272593 Author: Jungshik Shin <jshin@chromium.org> Date: Thu Jun 29 03:13:27 2017 Detect the OS timezone using JNI ICU timezone detection on Android does not work properly for most timezones. [1] Use JNI to detect the OS timezone and set the ICU default timezone accordingly both on ICU initialization and on timezone change. This is to reland https://chromium-review.googlesource.com/c/512282 with a temporary suppression of StrictMode check for disk read for devices that skipped the set-up wizard. [1] http://bugs.icu-project.org/trac/ticket/13208 TBR=mark@chromium.org,yfriedman@chromium.org,torne@chromium.org BUG= chromium:722821 , chromium:737475 TEST=Change the timezone on Android to a few different zones (e.g. Australia/Sydney, Asia/Seoul, Europe/Amstredam). At match what's chosen in Android settings. http: //jungshik.github.io/cr/bugs/722821.html , local tz should Change-Id: Ibc183295b46344d29f383851cf62697032e18777 Reviewed-on: https://chromium-review.googlesource.com/553717 Reviewed-by: Jungshik Shin <jshin@chromium.org> Reviewed-by: Yaron Friedman <yfriedman@chromium.org> Commit-Queue: Jungshik Shin <jshin@chromium.org> Cr-Commit-Position: refs/heads/master@{#483276} [modify] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/base/BUILD.gn [add] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/base/android/java/src/org/chromium/base/TimezoneUtils.java [add] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/base/android/timezone_utils.cc [add] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/base/android/timezone_utils.h [modify] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/base/i18n/icu_util.cc [modify] https://crrev.com/ffb4fbf926444cc3aecd111c98d1521993272593/services/device/time_zone_monitor/time_zone_monitor.cc
,
Aug 22 2017
Is this still on track for a mid september release?
,
Oct 15 2017
re: comment 50 https://www.chromium.org/developers/calendar : has the Chrome branch and releaase schedule. The CL recorded in comment 49 was landed on June 29, which was well in advance of M61 branch point. (July 20th). M61 turned stable on Sep 5. So, you should see the fix in M61.
,
Oct 15 2017
It is fixed! Thanks |
||||||||
►
Sign in to add a comment |
||||||||
Comment 1 by bokan@chromium.org
, May 16 2017