The Role of Locale in Tempo
The locale configuration setting (config.locale) is a foundational pillar of the Tempo engine. Because Tempo delegates heavily to native ECMAScript APIs (Intl and Temporal), the locale parameter is responsible for driving three distinct behavioral systems:
- Ambiguity Resolution (How ambiguous dates are ordered)
- Multi-lingual Parsing (How foreign text is lexed)
- Auto-localization Formatting (How output strings are generated)
When you initialize Tempo (or let it infer its environment), the locale dictates how it interprets and communicates dates.
1. Ambiguity Resolution (Date Layout)
When parsing an ambiguous string like 04/05/2024, the engine must decide if it's April 5th (MDY order) or May 4th (DMY order).
Tempo uses the active locale as a critical piece of metadata to resolve this:
- It resolves your
locale(e.g.'en-US'or'en-GB') to determine the active region. - It cross-references the locale's region or language against the internal
MONTH_DAYregistry to check its preferred layout. - If the locale inherently prefers
MDY(like in the United States), Tempo dynamically swaps its parsing order to attemptMonth-Day-Yearpatterns before it attemptsDay-Month-Yearpatterns.
For deeper details on layout configurations and ambiguous digits, see the Ambiguity Resolution Guide.
2. Multi-Lingual Parsing (Input)
By default, Tempo parses structural English abbreviations (e.g., Jan, Feb, Mon, Tue). However, Tempo is capable of natively parsing foreign languages by dynamically learning from the runtime environment.
When you nominate a non-English locale (or an array of locales like ['fr-FR', 'es-ES']):
- Tempo asks the native ECMAScript
IntlAPI how to spell months, weekdays, and relative events (like "tomorrow" or "yesterday") in the specified languages. - It dynamically compiles new, high-performance Regular Expressions containing these localized abbreviations.
- It injects these new patterns into its lexer, allowing Tempo to instantly understand strings like
'15 Janvier 2024'or'el próximo lunes'.
import { Tempo } from '@magmacomputing/tempo';
// Tempo learns French and Spanish at runtime!
Tempo.init({
locale: ['fr-FR', 'es-ES']
});
const a = new Tempo('15 janvier 2024'); // Matches French
const b = new Tempo('el próximo lunes'); // Matches SpanishFor more details on setting up and optimizing international parsing, see Internationalized Parsing.
3. Formatting (Output)
When generating human-readable output, Tempo uses the locale to ensure the resulting text is culturally accurate. It delegates this heavily to native Intl APIs for extreme performance.
- When calling
.toLocaleString(), Tempo automatically passes your configuredlocaletoTemporalso that dates and times are correctly formatted for that region. - When passing an
Intl.DateTimeFormatOptionsobject to.format(), you can include alocaleproperty to explicitly override the instance's locale for that specific formatting execution. - When using granular layout strings, you must explicitly use the
:localemodifier on structural tokens (e.g.,{mon:locale}or{wkd:locale}) to instruct Tempo to delegate rendering toIntl. If yourlocaleis an array of strings, theIntlengine will prioritize the first supported locale in the list. - When generating human-readable relative time durations (e.g., using
.since()), Tempo utilizesIntl.RelativeTimeFormatcombined with yourlocaleto produce fluid natural language strings (e.g., turning "2 days ago" into "hace 2 días" for Spanish).
const t = new Tempo('2024-02-15', { locale: ['fr-FR', 'en-US'] });
console.log(t.format('{wkd:locale}, {dd} {mon:locale} {yyyy}'));
// "jeudi, 15 février 2024"
console.log(t.format({ dateStyle: 'full', locale: 'de-DE' }));
// "Donnerstag, 15. Februar 2024"For more details on formatting features, see the Format Guide.
Global LOCALE Registry
The easiest way to augment or override translations globally is via the locales configuration option. Translations added here will apply to any plugin that resolves the specified key:
Tempo.init({
locale: 'fr-FR',
registry: {
locales: {
fr: {
morning: 'Matinée',
afternoon: 'Après-midi',
// Supports native Intl.PluralRules objects for ordinals!
ordinal: { one: 'er', other: 'e' }
}
}
}
});
const t = new Tempo('2024-05-15 10:30', { locale: 'fr-FR' });
console.log(t.format('{#tod:locale}')); // "Matinée"
console.log(t.format('{dd:ord}')); // "15e"NOTE
Ordinal Localization: While the :locale modifier automatically delegates to native APIs for months and weekdays, the :ord modifier requires a dictionary in the global locales registry for non-English languages. If no ordinal dictionary is found, Tempo will fall back to English suffixes (st, nd, rd, th). By providing a "Plural Object" mapping as shown above, Tempo natively evaluates the active Intl.PluralRules category and automatically appends the correct suffix!
Term Bundled Dictionary
Plugin authors can optionally bundle a locale dictionary directly into their custom Term definition:
Tempo.extend({
terms: [{
key: 'shift',
label: 'Shift',
locale: {
es: 'Turno',
de: 'Schicht'
},
// ... logic
}]
});Note: A user's Global locales config will always take precedence over a plugin's bundled dictionary.
Initialization & Fallbacks
If you do not explicitly provide a locale when initializing Tempo, it will gracefully attempt to infer it from the environment:
- It checks the browser's prioritized language list (
navigator.languages[0]). - It falls back to the system's primary language (
navigator.language). - If no system language is exposed (such as on headless servers without
Intlextensions), it falls back safely to'en-US'.
Whenever an array of locales is provided (e.g. ['fr-FR', 'en-GB']), Tempo extracts the first item in the array as the "Primary Locale". The primary locale is passed to strict native APIs (like Intl.Locale) to guarantee stable and deterministic formatting.