new Intl.DateTimeFormat(locales, options) turns a Date (Date) into local text. Use the presets dateStyle and timeStyle (full, long, medium, short), or pick components (weekday, year, month, day, hour, minute, timeZoneName...) and let the locale order them; mixing the two throws a TypeError. timeZone accepts IANA names such as Asia/Tokyo; hour12 or hourCycle override the clock; formatRange() prints spans such as "May 31 – Jun 4, 1999".
const d = new Date(Date.UTC(1999, 4, 31, 15, 30)); // 31 May 1999, 15:30 UTC
const opts = { dateStyle: 'full', timeStyle: 'short', timeZone: 'Asia/Tokyo' };
for (const locale of ['en-US', 'de-DE', 'ko-KR', 'ja-JP-u-ca-japanese']) {
console.log(new Intl.DateTimeFormat(locale, opts).format(d));
}
const custom = new Intl.DateTimeFormat('en-GB', {
weekday: 'short', day: 'numeric', month: 'short', hour: 'numeric', minute: '2-digit',
hour12: true, timeZone: 'America/New_York', timeZoneName: 'short',
});
console.log(custom.format(d), '|', custom.formatToParts(d)[0]);Tuesday, June 1, 1999 at 12:30 AM
Dienstag, 1. Juni 1999 um 00:30
1999년 6월 1일 화요일 AM 12:30
平成11年6月1日火曜日 0:30
Mon 31 May, 11:30 am GMT-4 | { type: 'weekday', value: 'Mon' }The instant is already Tuesday in Tokyo but still Monday in New York, and the Japanese calendar writes 1999 as Heisei 11. Without timeZone the device's zone applies, so server and browser can disagree: pass the zone explicitly.