i18n: Fix new Intl.DateTimeFormat("ja-u-tz-uslax")
Fix the locale parsing with tz which resolved to a tz name which
have a _ in it. "uslax" is resolved to "Los_Angles" and cause that.
TEST=In v8 or Chrome console, new Intl.DateTimeFormat("ja-u-tz-uslax") works fine.
resolvedOptions().timeZone is 'America/Los_Angenles'.
Bug: v8:8469
Change-Id: I996790b1ce59fbb5f6b0a460ff8acdb674894df1
Reviewed-on: https://chromium-review.googlesource.com/c/1372810
Reviewed-by: Jungshik Shin <jshin@chromium.org>
diff --git a/README.chromium b/README.chromium
index 5fbf9b3..e266952 100644
--- a/README.chromium
+++ b/README.chromium
@@ -266,3 +266,11 @@
- Fix:
https://github.com/unicode-org/icu/pull/265
https://github.com/unicode-org/icu/pull/278
+
+11. Locale parsing with tz unicode extension.
+
+ - patches/locale_id_tz_parsing.patch
+ - upstream bug:
+ https://unicode-org.atlassian.net/browse/ICU-11053
+ - Fix:
+ https://github.com/unicode-org/icu/pull/300
diff --git a/patches/locale_id_tz_parsing.patch b/patches/locale_id_tz_parsing.patch
new file mode 100644
index 0000000..910eb55
--- /dev/null
+++ b/patches/locale_id_tz_parsing.patch
@@ -0,0 +1,19 @@
+diff --git a/source/common/locid.cpp b/source/common/locid.cpp
+index e0dcc8a8..5d584bea 100644
+--- a/source/common/locid.cpp
++++ b/source/common/locid.cpp
+@@ -569,9 +569,13 @@ Locale& Locale::init(const char* localeID, UBool canonicalize)
+ variantBegin = length;
+
+ /* after uloc_getName/canonicalize() we know that only '_' are separators */
++ /* But _ could also appeared in timezone such as "en@timezone=America/Los_Angeles" */
+ separator = field[0] = fullName;
+ fieldIdx = 1;
+- while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 && fieldIdx < UPRV_LENGTHOF(field)-1) {
++ char* at = uprv_strchr(fullName, '@');
++ while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 &&
++ fieldIdx < UPRV_LENGTHOF(field)-1 &&
++ (at == nullptr || separator < at)) {
+ field[fieldIdx] = separator + 1;
+ fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
+ fieldIdx++;
diff --git a/source/common/locid.cpp b/source/common/locid.cpp
index e0dcc8a..5d584be 100644
--- a/source/common/locid.cpp
+++ b/source/common/locid.cpp
@@ -569,9 +569,13 @@
variantBegin = length;
/* after uloc_getName/canonicalize() we know that only '_' are separators */
+ /* But _ could also appeared in timezone such as "en@timezone=America/Los_Angeles" */
separator = field[0] = fullName;
fieldIdx = 1;
- while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 && fieldIdx < UPRV_LENGTHOF(field)-1) {
+ char* at = uprv_strchr(fullName, '@');
+ while ((separator = uprv_strchr(field[fieldIdx-1], SEP_CHAR)) != 0 &&
+ fieldIdx < UPRV_LENGTHOF(field)-1 &&
+ (at == nullptr || separator < at)) {
field[fieldIdx] = separator + 1;
fieldLen[fieldIdx-1] = (int32_t)(separator - field[fieldIdx-1]);
fieldIdx++;