Skip to content

Commit 9b86874

Browse files
codersjjJosh-Cena
andauthored
Reference for stage 2.7 intl-era-monthcode (mdn#42660)
* Fix incorrect Chinese calendar example in Temporal.PlainDate.from docs The Chinese calendar example incorrectly stated that year 2021 in the Chinese calendar corresponds to 616 BC in the ISO calendar. According to the TC39 Intl era and monthCode proposal, the Chinese calendar's epoch year is now ISO year 0, so year 2021 aligns with ISO year 2021. This commit: - Updates the Chinese calendar example comment to reflect the correct epoch year alignment - Corrects the expected output from "-000616-08-12[u-ca=chinese]" to "2021-08-08[u-ca=chinese]" - Adds a new Hebrew calendar example to demonstrate a calendar with a significantly different epoch year (5781 Hebrew = 2021 ISO) Fixes mdn#42565 * Fully document eras and monthCodes * Fixes --------- Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
1 parent d1bfebd commit 9b86874

File tree

19 files changed

+123
-66
lines changed

19 files changed

+123
-66
lines changed

.vscode/dictionaries/code-entities.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ BPPV1
8585
Brai
8686
braillelabel
8787
brailleroledescription
88+
broc
8889
browser-bottombox
8990
browser.safebrowsing
9091
browser.sessionhistory

.vscode/dictionaries/cultural-words.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Henkan
3232
Hijri
3333
Hinckley
3434
Hiroko
35-
háček
35+
Huangdi
3636
Jeonja
3737
Kayah
3838
Khema
@@ -80,9 +80,11 @@ Tangsa
8080
Thaana
8181
Tham
8282
Tirhuta
83+
Tishrei
8384
Tlayolotl
8485
Totnes
8586
Wancho
8687
Warang
8788
Zenkaku
8889
zhuyin
90+
Śaka

.vscode/dictionaries/proper-names.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ Kaku
306306
Kang
307307
Kaply
308308
Karmadrome
309+
KASI
309310
Kaspersky
310311
Katari
311312
Kazam

files/en-us/web/javascript/reference/global_objects/intl/supportedvaluesof/index.md

Lines changed: 29 additions & 27 deletions
Large diffs are not rendered by default.

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/era/index.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,33 @@ browser-compat: javascript.builtins.Temporal.PlainDate.era
77
sidebar: jsref
88
---
99

10-
The **`era`** accessor property of {{jsxref("Temporal.PlainDate")}} instances returns a calendar-specific lowercase string representing the era of this date, or `undefined` if the calendar does not use eras (e.g., ISO 8601). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. It is [calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent. For Gregorian, it is either `"gregory"` or `"gregory-inverse"`.
10+
The **`era`** accessor property of {{jsxref("Temporal.PlainDate")}} instances returns a calendar-specific lowercase string representing the era of this date, or `undefined` if the calendar does not use eras (e.g., ISO 8601). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. It is [calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent. For Gregorian, it is either `"ce"` or `"bce"`.
1111

12-
The set accessor of `era` is `undefined`. You cannot change this property directly. Use the {{jsxref("Temporal/PlainDate/with", "with()")}} method to create a new `Temporal.PlainDate` object with the desired new value. When setting eras, each code may have some aliases; for example, `"ce"` and `"ad"` are equivalent to `"gregory"`, and `"bce"` and `"bc"` are equivalent to `"gregory-inverse"`.
12+
## Value
13+
14+
All [specified calendars](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf#supported_calendar_types) have eras fully defined by the spec.
15+
16+
- The following calendars have a single era:
17+
- `buddhist`: `"be"`
18+
- `coptic`: `"am"`
19+
- `ethioaa`: `"aa"`
20+
- `hebrew`: `"am"`
21+
- `indian`: `"shaka"`
22+
- `persian`: `"ap"`
23+
- The following calendars have two eras. One is the _epoch era_, in which `eraYear` starts at 1 and is the same as {{jsxref("Temporal/PlainDate/year", "year")}}. The other is the inverse era, in which `eraYear` also starts at 1 and is equal to `1 - year` (so `eraYear: 1` corresponds to year `0`, `eraYear: 2` to year `-1`, etc.):
24+
- `gregory`: epoch era `"ce"`, inverse era `"bce"`
25+
- `islamic-civil`, `islamic-tbla`, `islamic-umalqura`: epoch era `"ah"`, inverse era `"bh"`
26+
- `roc`: epoch era `"roc"`, inverse era `"broc"`
27+
- The `ethiopic` calendar has an `"am"` era which is the epoch era. Years before `1` belong to the `"aa"` era, whose `eraYear` is equal to `year - 5500` (so `eraYear: -1000` corresponds to year `-6500`, `eraYear: 1` corresponds to year `-5499`, up to `eraYear: 5500` as year `0`).
28+
- The `japanese` calendar adds an era for each new emperor, so the output year and era for a future date may not match the input year and era when your code runs on a future engine version, and we won't enumerate them here. Each era's year starts at 1. It is also the only calendar known to have eras starting in the middle of a year, which means that the same `year` may correspond to different `(era, eraYear)` pairs depending on the month and day.
29+
`
30+
31+
> [!WARNING]
32+
> As of October 2025, in the `japanese` calendar, dates prior to 1868-10-23 ISO (the start date of the year 1 Meiji) don't work as expected in browsers in two ways. First, [CLDR had the wrong start date for the Meiji era](https://unicode-org.atlassian.net/browse/CLDR-11375), which causes calendar implementations to extend the Meiji era further to the past than it actually did. Second, the upcoming [Intl era and monthCode Proposal](https://tc39.es/proposal-intl-era-monthcode/) specifies that dates prior to 1873-01-01 ISO should use Gregorian eras, but browsers have traditionally used approximations of prior Japanese eras instead. The `japanese` calendar was taken into use on January 1, 6 Meiji / 1873-01-01 ISO, so these problems only affect proleptic dates.
33+
34+
- Other [specified calendars](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf#supported_calendar_types): `chinese`, `dangi`, `iso8601`, don't use eras and return `undefined`.
35+
36+
The set accessor of `era` is `undefined`. You cannot change this property directly. Use the {{jsxref("Temporal/PlainDate/with", "with()")}} method to create a new `Temporal.PlainDate` object with the desired new value. When setting eras, the `"ad"` and `"bc"` aliases are also accepted for the `"ce"` and `"bce"` eras of the `gregory` or `japanese` calendars.
1337

1438
> [!NOTE]
1539
> This string is not intended for display to users. Use {{jsxref("Temporal/PlainDate/toLocaleString", "toLocaleString()")}} with the appropriate options to get a localized string.
@@ -23,10 +47,10 @@ const date = Temporal.PlainDate.from("2021-07-01"); // ISO 8601 calendar
2347
console.log(date.era); // undefined
2448

2549
const date2 = Temporal.PlainDate.from("2021-07-01[u-ca=gregory]");
26-
console.log(date2.era); // gregory
50+
console.log(date2.era); // ce
2751

2852
const date3 = Temporal.PlainDate.from("-002021-07-01[u-ca=gregory]");
29-
console.log(date3.era); // gregory-inverse
53+
console.log(date3.era); // bce
3054

3155
const date4 = Temporal.PlainDate.from("2021-07-01[u-ca=japanese]");
3256
console.log(date4.era); // reiwa

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/erayear/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ sidebar: jsref
99

1010
The **`eraYear`** accessor property of {{jsxref("Temporal.PlainDate")}} instances returns a non-negative integer representing the year of this date within the era, or `undefined` if the calendar does not use eras (e.g., ISO 8601). The year index usually starts from 1 (more common) or 0, and years in an era can decrease with time (e.g., Gregorian BCE). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. It is [calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent.
1111

12-
Unlike `year`, `era` and `eraYear` may change in the middle of a calendar year. For example, Japan started the Reiwa era on May 1, 2019, so dates from 2019-01-01 to 2019-04-30 have `{ era: "heisei", eraYear: 31 }`, and dates from 2019-05-01 onwards have `{ era: "reiwa", eraYear: 1 }`, but the `year` is always 2019 (because the Japanese calendar uses the ISO 8601 year as the default year).
12+
Unlike `year`, `era` and `eraYear` may change in the middle of a calendar year. For example, Japan started the Reiwa era on May 1, 2019, so dates from 2019-01-01 to 2019-04-30 have `{ era: "heisei", eraYear: 31 }`, and dates from 2019-05-01 onwards have `{ era: "reiwa", eraYear: 1 }`, but the `year` is always 2019 (because the Japanese calendar uses the ISO 8601 year as the arithmetic year).
13+
14+
For more information about the values of `era` and `eraYear` for different calendars, see the {{jsxref("Temporal/PlainDate/era", "era")}} property.
1315

1416
The set accessor of `eraYear` is `undefined`. You cannot change this property directly. Use the {{jsxref("Temporal/PlainDate/with", "with()")}} method to create a new `Temporal.PlainDate` object with the desired new value.
1517

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/from/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,13 @@ const d3 = Temporal.PlainDate.from({
8585
year: 2021,
8686
month: 7,
8787
day: 1,
88-
calendar: "chinese",
88+
calendar: "hebrew",
8989
});
9090
// Note: when you construct a date with an object, the date components
9191
// are in *that* calendar, not the ISO calendar. However, toString() always
9292
// outputs the date in the ISO calendar. For example, the year "2021" in
93-
// the Chinese calendar is actually 616 BC in the ISO calendar.
94-
console.log(d3.toString()); // "-000616-08-12[u-ca=chinese]"
93+
// the Hebrew calendar is actually 1740 BCE in the ISO calendar.
94+
console.log(d3.toString()); // "-001739-03-07[u-ca=hebrew]"
9595

9696
// Era, eraYear, month, and day
9797
const d4 = Temporal.PlainDate.from({

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ These properties are defined on `Temporal.PlainDate.prototype` and shared by all
7575
- {{jsxref("Temporal/PlainDate/daysInYear", "Temporal.PlainDate.prototype.daysInYear")}}
7676
- : Returns a positive integer representing the number of days in the year of this date. [Calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent. For the ISO 8601 calendar, this is 365, or 366 in a leap year.
7777
- {{jsxref("Temporal/PlainDate/era", "Temporal.PlainDate.prototype.era")}}
78-
- : Returns a calendar-specific lowercase string representing the era of this date, or `undefined` if the calendar does not use eras (e.g., ISO 8601). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. [Calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent. For Gregorian, it is either `"gregory"` or `"gregory-inverse"`.
78+
- : Returns a calendar-specific lowercase string representing the era of this date, or `undefined` if the calendar does not use eras (e.g., ISO 8601). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. [Calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent. For Gregorian, it is either `"ce"` or `"bce"`.
7979
- {{jsxref("Temporal/PlainDate/eraYear", "Temporal.PlainDate.prototype.eraYear")}}
8080
- : Returns a non-negative integer representing the year of this date within the era, or `undefined` if the calendar does not use eras (e.g., ISO 8601). The year index usually starts from 1 (more common) or 0, and years in an era can decrease with time (e.g., Gregorian BCE). `era` and `eraYear` together uniquely identify a year in a calendar, in the same way that `year` does. [Calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent.
8181
- {{jsxref("Temporal/PlainDate/inLeapYear", "Temporal.PlainDate.prototype.inLeapYear")}}

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/monthcode/index.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ sidebar: jsref
99

1010
The **`monthCode`** accessor property of {{jsxref("Temporal.PlainDate")}} instances returns a calendar-specific string representing the month of this date. It is [calendar](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal#calendars)-dependent.
1111

12-
Usually it is `M` plus a two-digit month number. For leap months, it is the previous month's code followed by `L` (even if it's conceptually a derivative of the following month; for example, in the Hebrew calendar, Adar I has code `M05L` but Adar II has code `M06`). If the leap month is the first month of the year, the code is `M00L`.
12+
## Value
13+
14+
The basic format of `monthCode` is `M` plus a two-digit month number. For leap months, it is the previous month's code followed by `L` (even if it's conceptually a derivative of the following month; for example, in the Hebrew calendar, Adar I has code `M05L` but Adar II has code `M06`).
15+
16+
All calendars have at least 12 months, with codes from `"M01"` to `"M12"`.
17+
18+
All [specified calendars](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/supportedValuesOf#supported_calendar_types) have month codes fully defined by the spec. Most don't have month rules distinct from `iso8601`. The `coptic`, `ethioaa`, and `ethiopic` calendars have an additional `M13` month. The `chinese` and `dangi` calendars have 12 additional leap months possible, with codes from `"M01L"` to `"M12L"`. The `hebrew` calendar has one leap month, `"M05L"` (Adar I).
1319

1420
> [!NOTE]
1521
> Don't assume that `monthCode` is a user-friendly string; use `toLocaleString()` to format your date instead. Generally, don't cache the name of months in an array or object. Even though `monthCode` usually maps to the month's name within one calendar, we recommend always computing the month's name using, for example, `date.toLocaleString("en-US", { calendar: date.calendarId, month: "long" })`.
1622
1723
The set accessor of `monthCode` is `undefined`. You cannot change this property directly. Use the {{jsxref("Temporal/PlainDate/with", "with()")}} method to create a new `Temporal.PlainDate` object with the desired new value.
1824

25+
When setting the date to a different year, the `monthCode` remains the same, but the `month` may change if the target year has a different leap month structure. If the current `monthCode` does not exist in the target year and the method is not configured to reject, then for the `chinese` and `dangi` calendars, the previous month is used instead (e.g., from `"M03L"` to `"M03"`, which is from 闰三月 to 三月). For `hebrew`, the _next_ month is used instead (from `"M05L"` to `"M06"`, which is from Adar I to Adar II).
26+
1927
## Examples
2028

2129
### Using monthCode
@@ -70,7 +78,7 @@ Don't do this:
7078
```js example-bad
7179
const names = [
7280
"January", "February", "March", "April", "May", "June",
73-
"July", "August", "September", "October", "November", "December"
81+
"July", "August", "September", "October", "November", "December",
7482
];
7583

7684
const date = Temporal.PlainDate.from("2021-07-01");
@@ -84,7 +92,7 @@ Also don't do this:
8492
const names = {
8593
"M01": "January", "M02": "February", "M03": "March", "M04": "April",
8694
"M05": "May", "M06": "June", "M07": "July", "M08": "August",
87-
"M09": "September", "M10": "October", "M11": "November", "M12": "December"
95+
"M09": "September", "M10": "October", "M11": "November", "M12": "December",
8896
};
8997

9098
const date = Temporal.PlainDate.from("2021-07-01");

files/en-us/web/javascript/reference/global_objects/temporal/plaindate/plaindate/index.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ console.log(plainDate.toString()); // 2021-07-01
5959

6060
// Note that the date is stored internally as ISO 8601, even when it's
6161
// interpreted in a different calendar system. For example, even though
62-
// 2021-07-01 is 4658-05-22 in the Chinese calendar, you still pass the
62+
// 2021-07-01 ISO is 5781-10-21 in the Hebrew calendar, you still pass the
6363
// ISO date to the constructor.
64-
const plainDate2 = new Temporal.PlainDate(2021, 7, 1, "chinese");
65-
console.log(plainDate2.toString()); // 2021-07-01[u-ca=chinese]
66-
console.log(plainDate2.year); // 4658
67-
console.log(plainDate2.month); // 5
68-
console.log(plainDate2.day); // 22
64+
const plainDate2 = new Temporal.PlainDate(2021, 7, 1, "hebrew");
65+
console.log(plainDate2.toString()); // 2021-07-01[u-ca=hebrew]
66+
console.log(plainDate2.year); // 5781
67+
console.log(plainDate2.month); // 10
68+
console.log(plainDate2.day); // 21
6969
```
7070

7171
## Specifications

0 commit comments

Comments
 (0)