The date-fns internationalization system provides comprehensive support for 97+ languages and regions with customizable date formatting, relative time display, and cultural date conventions. All locale functionality is modular and tree-shakeable.
interface Locale {
code: string;
formatDistance?: FormatDistanceFn;
formatLong?: FormatLongOptions;
formatRelative?: FormatRelativeFn;
localize?: LocalizeOptions;
match?: MatchOptions;
options?: LocaleOptions;
}The locale object contains all language-specific formatting rules and translations needed for date operations in different languages and regions.
English Variants
enUS - English (United States) - DefaultenGB - English (United Kingdom)enCA - English (Canada)enAU - English (Australia)enNZ - English (New Zealand)enIN - English (India)enIE - English (Ireland)enZA - English (South Africa)European Languages
de - German (Germany)deAT - German (Austria)fr - French (France)frCA - French (Canada)frCH - French (Switzerland)es - Spanish (Spain)it - Italian (Italy)itCH - Italian (Switzerland)pt - Portuguese (Portugal)ptBR - Portuguese (Brazil)nl - Dutch (Netherlands)nlBE - Dutch (Belgium)Nordic Languages
da - Danishsv - Swedishnb - Norwegian Bokmålnn - Norwegian Nynorskfi - Finnishis - IcelandicSlavic Languages
ru - Russianpl - Polishcs - Czechsk - Slovaksl - Slovenianhr - Croatiansr - Serbian (Cyrillic)srLatn - Serbian (Latin)bg - Bulgarianmk - Macedonianbe - BelarusianbeTarask - Belarusian (Taraskievica)uk - UkrainianAsian Languages
zhCN - Chinese (Simplified, China)zhHK - Chinese (Traditional, Hong Kong)zhTW - Chinese (Traditional, Taiwan)ja - JapanesejaHira - Japanese (Hiragana)ko - Koreanth - Thaivi - Vietnamesehi - Hindibn - Bengaligu - Gujaratikn - Kannadata - Tamilte - TeluguMiddle Eastern & African
ar - ArabicarDZ - Arabic (Algeria)arEG - Arabic (Egypt)arMA - Arabic (Morocco)arSA - Arabic (Saudi Arabia)arTN - Arabic (Tunisia)he - HebrewfaIR - Persian (Iran)tr - Turkishaf - Afrikaans// Import specific locales
import { enUS, de, fr, ja, zhCN, ar } from "date-fns/locale";
// Available locales (97 total)
const locales = [
'af', 'ar', 'arDZ', 'arEG', 'arMA', 'arSA', 'arTN',
'az', 'be', 'beTarask', 'bg', 'bn', 'bs', 'ca', 'ckb',
'cs', 'cy', 'da', 'de', 'deAT', 'el', 'enAU', 'enCA',
'enGB', 'enIE', 'enIN', 'enNZ', 'enUS', 'enZA', 'eo',
'es', 'et', 'eu', 'faIR', 'fi', 'fr', 'frCA', 'frCH',
'fy', 'gd', 'gl', 'gu', 'he', 'hi', 'hr', 'ht', 'hu',
'hy', 'id', 'is', 'it', 'itCH', 'ja', 'jaHira', 'ka',
'kk', 'km', 'kn', 'ko', 'lb', 'lt', 'lv', 'mk', 'mn',
'ms', 'mt', 'nb', 'nl', 'nlBE', 'nn', 'oc', 'pl', 'pt',
'ptBR', 'ro', 'ru', 'se', 'sk', 'sl', 'sq', 'sr', 'srLatn',
'sv', 'ta', 'te', 'th', 'tr', 'ug', 'uk', 'uz', 'uzCyrl',
'vi', 'zhCN', 'zhHK', 'zhTW'
];import { format, formatDistance, formatRelative } from "date-fns";
import { de, fr, ja, zhCN } from "date-fns/locale";
const date = new Date(2014, 1, 11);
// German
format(date, "EEEE, do MMMM yyyy", { locale: de });
//=> 'Dienstag, 11. Februar 2014'
// French
format(date, "EEEE, do MMMM yyyy", { locale: fr });
//=> 'mardi, 11e février 2014'
// Japanese
format(date, "EEEE, do MMMM yyyy", { locale: ja });
//=> '火曜日, 11日 2月 2014'
// Chinese (Simplified)
format(date, "EEEE, do MMMM yyyy", { locale: zhCN });
//=> '星期二, 11日 二月 2014'import { formatDistance, formatDistanceToNow } from "date-fns";
import { de, es, ru, ar } from "date-fns/locale";
const date1 = new Date(2014, 6, 2);
const date2 = new Date(2015, 0, 1);
// German
formatDistance(date2, date1, { locale: de });
//=> 'etwa 6 Monate'
// Spanish
formatDistance(date2, date1, { locale: es });
//=> 'alrededor de 6 meses'
// Russian
formatDistance(date2, date1, { locale: ru });
//=> 'около 6 месяцев'
// Arabic
formatDistance(date2, date1, { locale: ar });
//=> 'حوالي 6 أشهر'import { formatRelative } from "date-fns";
import { de, fr, ja } from "date-fns/locale";
const baseDate = new Date(2000, 0, 1, 0, 0, 0); // Jan 1, 2000
const date = new Date(1999, 11, 27); // Dec 27, 1999
// German
formatRelative(date, baseDate, { locale: de });
//=> 'letzten Montag um 00:00'
// French
formatRelative(date, baseDate, { locale: fr });
//=> 'lundi dernier à 00:00'
// Japanese
formatRelative(date, baseDate, { locale: ja });
//=> '先週の月曜日 0:00'import { format, startOfWeek } from "date-fns";
import { de, ar, enUS } from "date-fns/locale";
const date = new Date(2014, 1, 11); // Tuesday
// Different week start days by locale
startOfWeek(date, { locale: enUS }); // Sunday start
//=> Sun Feb 09 2014
startOfWeek(date, { locale: de }); // Monday start
//=> Mon Feb 10 2014
// Manual override
startOfWeek(date, { locale: enUS, weekStartsOn: 1 }); // Force Monday start
//=> Mon Feb 10 2014import { getWeek } from "date-fns";
import { de, enUS } from "date-fns/locale";
const date = new Date(2014, 0, 1); // Jan 1, 2014
// Different first week rules
getWeek(date, { locale: enUS });
//=> 1 (US: week containing Jan 1 is week 1)
getWeek(date, { locale: de });
//=> 1 (German: week with 4+ days in new year is week 1)import { format } from "date-fns";
import { enUS, de, ja, ar } from "date-fns/locale";
const date = new Date(2014, 1, 11);
// US format (M/d/yyyy)
format(date, "P", { locale: enUS });
//=> '2/11/2014'
// German format (dd.MM.yyyy)
format(date, "P", { locale: de });
//=> '11.02.2014'
// Japanese format (yyyy/MM/dd)
format(date, "P", { locale: ja });
//=> '2014/02/11'
// Arabic format (d/M/yyyy)
format(date, "P", { locale: ar });
//=> '11/2/2014'import { format } from "date-fns";
import { enUS, de, ja } from "date-fns/locale";
const date = new Date(2014, 1, 11, 14, 30);
// US format (2:30 PM)
format(date, "p", { locale: enUS });
//=> '2:30 PM'
// German format (14:30)
format(date, "p", { locale: de });
//=> '14:30'
// Japanese format (14:30)
format(date, "p", { locale: ja });
//=> '14:30'import { format } from "date-fns";
import { enUS, de, fr, ja } from "date-fns/locale";
const date = new Date(2014, 1, 11, 14, 30, 45);
// Full date and time formats
format(date, "PPPPpppp", { locale: enUS });
//=> 'Tuesday, February 11th, 2014 at 2:30:45 PM GMT+2'
format(date, "PPPPpppp", { locale: de });
//=> 'Dienstag, 11. Februar 2014 um 14:30:45 GMT+2'
format(date, "PPPPpppp", { locale: fr });
//=> 'mardi 11 février 2014 à 14:30:45 GMT+2'
format(date, "PPPPpppp", { locale: ja });
//=> '2014年2月11日火曜日 14:30:45 GMT+2'interface Locale {
code: string;
formatDistance: FormatDistanceFn;
formatLong: FormatLongOptions;
formatRelative: FormatRelativeFn;
localize: LocalizeOptions;
match: MatchOptions;
options?: LocaleOptions;
}import { Locale } from "date-fns";
const customLocale: Locale = {
code: 'custom',
formatDistance: (token, count, options) => {
// Custom distance formatting logic
const formatDistanceLocale = {
lessThanXSeconds: 'less than {{count}} second{{s}}',
xSeconds: '{{count}} second{{s}}',
halfAMinute: 'half a minute',
lessThanXMinutes: 'less than {{count}} minute{{s}}',
xMinutes: '{{count}} minute{{s}}',
aboutXHours: 'about {{count}} hour{{s}}',
xHours: '{{count}} hour{{s}}',
xDays: '{{count}} day{{s}}',
aboutXWeeks: 'about {{count}} week{{s}}',
xWeeks: '{{count}} week{{s}}',
aboutXMonths: 'about {{count}} month{{s}}',
xMonths: '{{count}} month{{s}}',
aboutXYears: 'about {{count}} year{{s}}',
xYears: '{{count}} year{{s}}',
overXYears: 'over {{count}} year{{s}}',
almostXYears: 'almost {{count}} year{{s}}'
};
const result = formatDistanceLocale[token].replace(
'{{count}}',
count.toString()
);
return result.replace('{{s}}', count === 1 ? '' : 's');
},
formatLong: {
time: 'HH:mm:ss',
date: 'dd/MM/yyyy',
dateTime: '{{date}} {{time}}',
longDate: 'MMMM d, yyyy',
fullDate: 'EEEE, MMMM do, yyyy',
shortTime: 'HH:mm',
longTime: 'HH:mm:ss',
fullTime: 'HH:mm:ss'
},
formatRelative: (token, date, baseDate, options) => {
// Custom relative formatting
const formatRelativeLocale = {
lastWeek: "'last' eeee 'at' p",
yesterday: "'yesterday at' p",
today: "'today at' p",
tomorrow: "'tomorrow at' p",
nextWeek: "eeee 'at' p",
other: 'P'
};
return formatRelativeLocale[token];
},
localize: {
// Month names, day names, etc.
month: (month) => ['Jan', 'Feb', 'Mar', /*...*/][month],
day: (day) => ['Sun', 'Mon', 'Tue', /*...*/][day],
// Additional localization functions...
},
match: {
// Parsing patterns for custom locale
// Match functions for parsing formatted dates
},
options: {
weekStartsOn: 1, // Monday
firstWeekContainsDate: 4
}
};import { format } from "date-fns";
// Use the custom locale
format(new Date(), "PPP", { locale: customLocale });// Browser locale detection
function getBrowserLocale(): string {
return navigator.language || navigator.languages[0] || 'en-US';
}
// Map browser locale to date-fns locale
function getDateFnsLocale(browserLocale: string): Locale {
const localeMap: Record<string, () => Promise<Locale>> = {
'de': () => import('date-fns/locale/de'),
'de-DE': () => import('date-fns/locale/de'),
'fr': () => import('date-fns/locale/fr'),
'fr-FR': () => import('date-fns/locale/fr'),
// Add more mappings...
};
const loader = localeMap[browserLocale] ||
localeMap[browserLocale.split('-')[0]] ||
(() => import('date-fns/locale/en-US'));
return loader();
}// Lazy load locales
class LocaleManager {
private loadedLocales = new Map<string, Locale>();
async getLocale(code: string): Promise<Locale> {
if (this.loadedLocales.has(code)) {
return this.loadedLocales.get(code)!;
}
try {
const locale = await import(`date-fns/locale/${code}`);
this.loadedLocales.set(code, locale.default);
return locale.default;
} catch {
// Fallback to English
const enUS = await import('date-fns/locale/en-US');
return enUS.default;
}
}
}import { format } from "date-fns";
import { ar, he } from "date-fns/locale";
const date = new Date(2014, 1, 11);
// Arabic (RTL)
format(date, "EEEE، do MMMM yyyy", { locale: ar });
//=> 'الثلاثاء، 11 فبراير 2014'
// Hebrew (RTL)
format(date, "EEEE, do MMMM yyyy", { locale: he });
//=> 'יום שלישי, 11 פברואר 2014'import { ar, he, enUS } from "date-fns/locale";
function isRTLLocale(locale: Locale): boolean {
const rtlCodes = ['ar', 'he', 'fa', 'ur'];
return rtlCodes.includes(locale.code);
}
function formatWithDirection(date: Date, pattern: string, locale: Locale): {
text: string;
direction: 'ltr' | 'rtl';
} {
return {
text: format(date, pattern, { locale }),
direction: isRTLLocale(locale) ? 'rtl' : 'ltr'
};
}interface LocaleOptions {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7;
}interface FormatLongOptions {
time?: string;
date?: string;
dateTime?: string;
longDate?: string;
fullDate?: string;
shortTime?: string;
longTime?: string;
fullTime?: string;
}type FormatDistanceFn = (
token: string,
count: number,
options?: { addSuffix?: boolean; comparison?: number }
) => string;type FormatRelativeFn = (
token: 'lastWeek' | 'yesterday' | 'today' | 'tomorrow' | 'nextWeek' | 'other',
date: Date,
baseDate: Date,
options?: any
) => string;