Tech · · 7 min read
The first day of the week, without a lookup table
Intl.Locale's info methods are Baseline as of July 2026. What getWeekInfo(), getTextInfo() and getCalendars() return, with real values across Asia-Pacific locales.
Every date picker has to answer one question before it can draw a single row: which day does the week start on? JavaScript now answers it without a hand-maintained map of countries:
new Intl.Locale("en-AU").getWeekInfo(); // { firstDay: 1, weekend: [6, 7] }
new Intl.Locale("ja-JP").getWeekInfo(); // { firstDay: 7, weekend: [6, 7] }
new Intl.Locale("en-IN").getWeekInfo(); // { firstDay: 7, weekend: [7] }Days are numbered as in ISO 8601: 1 is Monday and 7 is Sunday. Australia starts the week on Monday, Japan and India on Sunday, and India's weekend is a single day.
These methods are part of the Intl Locale Info API, which reached Stage 4 at TC39 in November 2025, was folded into the 13th edition of ECMA-402 in June 2026, and became Baseline newly available on 21 July 2026 when Firefox 153 shipped it.
github.com ↗TC39 proposal-intl-locale-infoThe proposal repository, with the design history and the dropped parts of the original scope. Source: TC39The seven methods
Each one is a method on an Intl.Locale instance, and each returns data the browser already carries for formatting.
| Method | Returns |
|---|---|
getWeekInfo() | { firstDay, weekend } — the first weekday, and which days are the weekend |
getTextInfo() | { direction } — "ltr" or "rtl" |
getCalendars() | Calendar identifiers used in the locale, preferred one first |
getTimeZones() | IANA time zone identifiers in common use in the region, sorted |
getNumberingSystems() | Numbering system identifiers, such as latn or arab |
getHourCycles() | Hour cycle identifiers, such as h12 or h23 |
getCollations() | Sort order identifiers available for the locale |
Two shapes are worth memorising exactly, because the conformance suite pins them down: getWeekInfo() returns an object whose only own properties are firstDay and weekend, and getTextInfo() returns an object whose only own property is direction.
If you remember a third minimalDays property, you're remembering an earlier draft. Implementations that shipped the first version of this API exposed it, but it is not part of the standard return value — test262 asserts the own keys are exactly firstDay and weekend. Don't build week-numbering logic on it.
What the values look like across Asia-Pacific
The data comes from CLDR, the same source browsers use for every other Intl decision. Values below were read from ICU 78.2, through the accessor form described later in this article, and the mix is more varied than a single "Sunday or Monday" switch would suggest.
| Locale | First day | Weekend | Preferred calendars | Hour cycle |
|---|---|---|---|---|
en-AU | Monday | Sat, Sun | gregory | h12 |
en-NZ | Monday | Sat, Sun | gregory | h12 |
zh-CN | Monday | Sat, Sun | gregory, chinese | h23 |
ja-JP | Sunday | Sat, Sun | gregory, japanese | h23 |
ko-KR | Sunday | Sat, Sun | gregory, dangi | h12 |
zh-TW | Sunday | Sat, Sun | gregory, roc, chinese | h12 |
en-SG | Sunday | Sat, Sun | gregory, chinese | h12 |
id-ID | Sunday | Sat, Sun | gregory, islamic and two variants | h23 |
th-TH | Sunday | Sat, Sun | buddhist, gregory | h23 |
en-IN | Sunday | Sun only | gregory, indian | h12 |
Three of these will break an interface that assumes otherwise:
- India's weekend is one day.
weekend: [7]means a "weekend" column pair, a Saturday-and-Sunday greyed-out rule, or an availability calculation that blocks two days is wrong foren-INandhi-IN. - Mainland China starts the week on Monday; Taiwan starts on Sunday. Same language, different
firstDay. Region matters, not script. - Thailand's preferred calendar isn't Gregorian.
getCalendars()returnsbuddhistfirst forth-TH, which is why a Thai user may expect the year 2569 where your UI shows 2026. The API tells you the preference; honouring it is a separate decision.
A month grid that gets the order right
getWeekInfo() gives you the rotation; Intl.DateTimeFormat gives you the labels. One function covers both, plus which columns to mark as weekend:
function weekdayHeaders(locale) {
const { firstDay, weekend } = new Intl.Locale(locale).getWeekInfo();
const fmt = new Intl.DateTimeFormat(locale, { weekday: "short", timeZone: "UTC" });
return Array.from({ length: 7 }, (_, i) => {
const iso = ((firstDay - 1 + i) % 7) + 1; // 1 = Monday … 7 = Sunday
const date = new Date(Date.UTC(2026, 5, iso)); // 1 June 2026 was a Monday
return { iso, label: fmt.format(date), isWeekend: weekend.includes(iso) };
});
}Picking a month whose 1st falls on a Monday means ISO day n is simply the nth of that month, so no date arithmetic is needed. Run against CLDR data, the labels and weekend flags come out as:
en-AU Mon Tue Wed Thu Fri Sat* Sun*
en-IN Sun* Mon Tue Wed Thu Fri Sat
ja-JP 日* 月 火 水 木 金 土*
zh-CN 周一 周二 周三 周四 周五 周六* 周日*Never hardcode the weekday labels themselves. Intl.DateTimeFormat with weekday: "short" or "narrow" produces the right ones, in the right script, for free.
What it won't tell you
The API reports locale conventions, not business rules. It has nothing to say about:
- Public holidays. No browser API exposes them. That stays your data problem, and it is a per-country, per-year problem.
- Working days. A weekend is a locale convention; a hospital roster or a trading calendar is not.
- Week numbering. With
minimalDaysgone from the standard, the rule for which week is week 1 is not available here. - The user's preference. This is locale data, not user settings. Someone in Tokyo who wants Monday-first still needs a preference of their own.
The API shipped twice, so feature-detect
The first version of this feature exposed getters — locale.weekInfo, locale.textInfo, locale.calendars — and shipped in Chrome 99 (March 2022) and Safari 15.4. The committee then changed the design to methods, which is what the standard specifies and what Firefox implemented directly. Both forms exist in the wild, and Node 22 still ships the accessor form.
Detect the method, then the accessor, then fall back:
function weekInfo(locale, fallback = { firstDay: 1, weekend: [6, 7] }) {
const l = new Intl.Locale(locale);
if (typeof l.getWeekInfo === "function") return l.getWeekInfo();
if (l.weekInfo) return l.weekInfo; // older accessor form
return fallback;
}Choose the fallback for your actual audience rather than copying en-US. Also note that getTimeZones() needs a region to answer: new Intl.Locale("en") has no country attached, and there is no list of time zones "in common use" for a bare language, so guard that call.
Browser support
| Browser | Methods since | Released |
|---|---|---|
| Safari | 17 | 18 September 2023 |
| Chrome | 130 | 15 October 2024 |
| Edge | 130 | 17 October 2024 |
| Firefox | 153 | 21 July 2026 |
Firefox was last, which set the Baseline keystone date. Firefox 153 is also the current ESR at the time of writing, which matters if you support long-term-support Firefox in managed environments. Support data from @mdn/browser-compat-data 8.1.1.
One more caveat that applies at every support level: these values are CLDR data shipped inside the browser's ICU build. They are stable in practice, not immutable — CLDR revises region data between releases. Read them at runtime, and don't assert exact values in tests you need to stay green.
FAQ
Is firstDay 1 Monday or Sunday?
Monday. The numbering follows ISO 8601, so 1 is Monday and 7 is Sunday. Locales that start the week on Sunday, such as ja-JP and en-US, report firstDay: 7.
How do I get the user's own locale rather than a fixed one?
new Intl.Locale(navigator.language) for the browser's preferred locale, or read new Intl.DateTimeFormat().resolvedOptions().locale for the one Intl actually resolved to.
Does getCalendars() mean I should switch my UI to that calendar?
No. It tells you which calendars the locale uses and which is preferred. Whether to render the Buddhist or Japanese calendar is a product decision — but it explains why some users expect a different year.
Can I use it today without a fallback?
Not safely. It is Baseline newly available rather than widely available, so visitors on older Firefox or older Safari will not have the methods. The detection above is a handful of lines.
Sources
- ECMA-402, 13th edition (June 2026) — the edition that adopted the Intl Locale Info API
- TC39 proposal-intl-locale-info — scope, design history and Stage 4 advancement
- test262 —
Intl.Locale.prototype.getWeekInfo— the conformance tests pinning the return shape @mdn/browser-compat-data— version and release-date data, package version 8.1.1web-features— Baseline status and keystone date for Intl.Locale info- Unicode CLDR — the source of the week, calendar and time zone data browsers expose
More to read
- Design
Design · · 5 min read
Your video player's state is now a CSS selector
Seven pseudo-classes match audio and video by playback state, and Chromium shipped them in August 2026. What each matches, and the overlap that trips people up.
- Tech
Tech · · 5 min read
CSS progress() is Baseline. It is not what the name suggests
progress() returns how far one value sits between two others, as a number from 0 to 1. What it computes, the fluid typography it simplifies, and what it doesn't do.