diff --git a/src/impl/locale.js b/src/impl/locale.js index d3cb34744..407336b57 100644 --- a/src/impl/locale.js +++ b/src/impl/locale.js @@ -75,22 +75,26 @@ function parseLocaleString(localeStr) { return [localeStr]; } else { let options; + let selectedStr; const smaller = localeStr.substring(0, uIndex); try { options = getCachedDTF(localeStr).resolvedOptions(); + selectedStr = localeStr; } catch (e) { options = getCachedDTF(smaller).resolvedOptions(); + selectedStr = smaller; } const { numberingSystem, calendar } = options; - // return the smaller one so that we can append the calendar and numbering overrides to it - return [smaller, numberingSystem, calendar]; + return [selectedStr, numberingSystem, calendar]; } } function intlConfigString(localeStr, numberingSystem, outputCalendar) { if (outputCalendar || numberingSystem) { - localeStr += "-u"; + if (!localeStr.includes("-u-")) { + localeStr += "-u"; + } if (outputCalendar) { localeStr += `-ca-${outputCalendar}`; diff --git a/test/datetime/create.test.js b/test/datetime/create.test.js index 446ad9e6f..c14d13e6e 100644 --- a/test/datetime/create.test.js +++ b/test/datetime/create.test.js @@ -663,7 +663,7 @@ test("DateTime.fromObject accepts a locale", () => { test("DateTime.fromObject accepts a locale with calendar and numbering identifiers", () => { const res = DateTime.fromObject({}, { locale: "be-u-ca-coptic-nu-mong" }); - expect(res.locale).toBe("be"); + expect(res.locale).toBe("be-u-ca-coptic-nu-mong"); expect(res.outputCalendar).toBe("coptic"); expect(res.numberingSystem).toBe("mong"); }); @@ -677,7 +677,7 @@ test("DateTime.fromObject accepts a locale string with weird junk in it", () => } ); - expect(res.locale).toBe("be"); + expect(res.locale).toBe("be-u-ca-coptic-ca-islamic"); // "coptic" is right, but some versions of Node 10 give "gregory" expect(res.outputCalendar === "gregory" || res.outputCalendar === "coptic").toBe(true); @@ -695,7 +695,7 @@ test("DateTime.fromObject overrides the locale string with explicit settings", ( } ); - expect(res.locale).toBe("be"); + expect(res.locale).toBe("be-u-ca-coptic-nu-mong"); expect(res.outputCalendar).toBe("islamic"); expect(res.numberingSystem).toBe("thai"); }); diff --git a/test/datetime/format.test.js b/test/datetime/format.test.js index 823dce354..23dcfd77a 100644 --- a/test/datetime/format.test.js +++ b/test/datetime/format.test.js @@ -415,6 +415,12 @@ test("DateTime#toLocaleString uses locale-appropriate time formats", () => { expect(dt.reconfigure({ locale: "es" }).toLocaleString(DateTime.TIME_24_SIMPLE)).toBe("9:23"); }); +test("DateTime#toLocaleString() respects language tags", () => { + expect(dt.reconfigure({ locale: "en-US-u-hc-h23" }).toLocaleString(DateTime.TIME_SIMPLE)).toBe( + "09:23" + ); +}); + test("DateTime#toLocaleString() accepts a zone even when the zone is set", () => { expect( dt.toLocaleString({