Skip to content

Commit

Permalink
preserve language tags (#1354)
Browse files Browse the repository at this point in the history
  • Loading branch information
devsnek committed Jan 3, 2023
1 parent acc4952 commit 806467a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 8 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Here are some vague notes on Luxon's design philosophy:

## Building and testing

Building and testing is done through npm scripts. The tests run in Node and require Node 10+ with full-icu support. This is because some of the features available in Luxon (like internationalization and time zones) need that stuff and we test it all. On any platform, if you have Node 10 installed with full-icu, you're good to go; just run npm scripts like `npm run test`. But you probably don't have that, so read on.
Building and testing is done through npm scripts. The tests run in Node and require Node 18 with full-icu support. This is because some of the features available in Luxon (like internationalization and time zones) need that stuff and we test it all. On any platform, if you have Node 18 installed with full-icu, you're good to go; just run `scripts/test`. But you probably don't have that, so read on.

### OSX

Expand Down
20 changes: 16 additions & 4 deletions src/impl/locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,27 +70,39 @@ function parseLocaleString(localeStr) {
// b) if it does, use Intl to resolve everything
// c) if Intl fails, try again without the -u

// private subtags and unicode subtags have ordering requirements,
// and we're not properly parsing this, so just strip out the
// private ones if they exist.
const xIndex = localeStr.indexOf("-x-");
if (xIndex !== -1) {
localeStr = localeStr.substring(0, xIndex);
}

const uIndex = localeStr.indexOf("-u-");
if (uIndex === -1) {
return [localeStr];
} else {
let options;
const smaller = localeStr.substring(0, uIndex);
let selectedStr;
try {
options = getCachedDTF(localeStr).resolvedOptions();
selectedStr = localeStr;
} catch (e) {
const smaller = localeStr.substring(0, uIndex);
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}`;
Expand Down
21 changes: 18 additions & 3 deletions test/datetime/create.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
});
Expand All @@ -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);
Expand All @@ -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");
});
Expand Down Expand Up @@ -811,3 +811,18 @@ test("DateTime.fromObject takes a undefined to mean {}", () => {
const res = DateTime.fromObject();
expect(res.year).toBe(new Date().getFullYear());
});

test("private language subtags don't break unicode subtags", () => {
const res = DateTime.fromObject(
{},
{
locale: "be-u-ca-coptic-nu-mong-x-twain",
numberingSystem: "thai",
outputCalendar: "islamic",
}
);

expect(res.locale).toBe("be-u-ca-coptic-nu-mong");
expect(res.outputCalendar).toBe("islamic");
expect(res.numberingSystem).toBe("thai");
});
6 changes: 6 additions & 0 deletions test/datetime/format.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down

0 comments on commit 806467a

Please sign in to comment.