Skip to content

i18n formatting

atemporal uses Intl.DateTimeFormat for locale-aware formatting, so all standard BCP 47 locale tags work out of the box.

Default locale

ts
import atemporal from 'atemporal';

atemporal.setDefaultLocale('es');
atemporal('2024-01-15T12:34:56Z').format({ dateStyle: 'full', timeStyle: 'short' });
// 'lunes, 15 de enero de 2024, 12:34'

Per-call override

ts
atemporal('2024-01-15T12:34:56Z').format(
  { dateStyle: 'long' },
  'fr'
);
// '15 janvier 2024'

Common locales cheat-sheet

LocaleSample output (dateStyle: 'long')
enJanuary 15, 2024
en-GB15 January 2024
es15 de enero de 2024
fr15 janvier 2024
de15. Januar 2024
ja2024年1月15日
zh2024年1月15日
ar١٥ يناير ٢٠٢٤ (RTL)
he15 בינואר 2024 (RTL)

Token strings vs Intl options

atemporal supports two formatting modes:

ModeExampleWhen to use
Token.format('YYYY-MM-DD')Stable, machine-readable, log-friendly
Intl opts.format({ dateStyle: 'full' })Locale-aware, user-facing, "natural"

The token mode is not localized. MMMM is always the English month name. If you need "January" / "enero" / "1月", use the Intl options mode.

Mixed: token + locale

ts
// Locale-aware weekday name with token-style date
atemporal('2024-01-15').format('DD [de] MMMM [de] YYYY', 'es');
// '15 de enero de 2024'

The [...] escapes literal text; the rest is replaced with the locale-aware month name. (atemporal's [literal] escape syntax is moment-compatible.)

i18n catalog

The i18n module has standard message catalogs. To localize errors, see the logging recipe — the code field is what you index on, then look up the localized message in your catalog.

ts
// i18n.ts
const messages = {
  es: { ATEMPORAL_INVALID_DATE: 'La fecha no es válida.' },
  en: { ATEMPORAL_INVALID_DATE: 'The date is not valid.' },
};

export function t(code: string, locale = 'en'): string {
  return messages[locale]?.[code] ?? messages.en[code] ?? code;
}

Bundling considerations

Intl.DateTimeFormat ships with a large CLDR dataset. V8/Node.js bake the data into the binary. Browsers ship it per user-agent.

  • Node.js: the data is already there; no extra cost.
  • Browsers: same.
  • Cloudflare Workers: the data is in V8; cost is ~80 KB.
  • Deno: same as Node.

There is no atemporal-side bundle penalty for supporting all locales.

See also