Date и Intl: интернационализация
Date— встроенный объект JavaScript для работы с датами и временем;Intl— API интернационализации для форматирования чисел, дат, строк в соответствии с локалью пользователя.
Зачем нужно
Без Intl форматирование дат и чисел требовало бы ручного кода или тяжёлых библиотек (Moment.js, day.js). Современный Intl встроен в браузер и Node.js и покрывает 95% задач: локализованные даты, валюты, числа, относительное время («3 часа назад»), сортировку строк по локали. Date — основа для работы с временными метками, хотя его API неудобен для сложных манипуляций.
Где используется
- Форматирование дат в интерфейсе: «10 апреля 2026» вместо
2026-04-10 - Валюта и числа:
1 500,00 ₽или$1,500.00в зависимости от локали - Относительное время: «3 минуты назад», «через 2 дня» через
Intl.RelativeTimeFormat - Сортировка строк с учётом языка:
Intl.Collatorдля правильного порядка кириллицы - Пагинация дат: вычисление разницы, добавление дней/месяцев
Основной контент
Date — создание и основные операции
// Создание
const now = new Date();
const specific = new Date('2026-04-10'); // ISO 8601
const byParts = new Date(2026, 3, 10); // Внимание: месяц 0-based!
const fromTimestamp = new Date(1712707200000);
// Получение компонентов (локальное время)
now.getFullYear(); // 2026
now.getMonth(); // 0-11 (январь = 0!)
now.getDate(); // 1-31
now.getDay(); // 0-6 (воскресенье = 0)
now.getHours(); // 0-23
now.getMinutes(); // 0-59
// UTC-версии
now.getUTCFullYear;
now.getUTCHours;
// Временная метка
now.getTime(); // миллисекунды с 1970-01-01 UTC
Date.now(); // то же без создания объекта (производительнее)
// Вычисление разницы в днях
function daysBetween(a, b) {
return Math.round(Math.abs(b - a) / (1000 * 60 * 60 * 24));
}
// Добавление дней
function addDays(date, days) {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
}
Intl.DateTimeFormat — локализованное форматирование дат
const date = new Date('2026-04-10T14:30:00');
// Базовое форматирование
new Intl.DateTimeFormat('ru-RU').format(date); // '10.04.2026'
new Intl.DateTimeFormat('en-US').format(date); // '4/10/2026'
new Intl.DateTimeFormat('de-DE').format(date); // '10.4.2026'
// Детальный контроль
new Intl.DateTimeFormat('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit'
}).format(date);
// 'пятница, 10 апреля 2026 г., 14:30'
// Переиспользуемый форматтер
const dateFormatter = new Intl.DateTimeFormat('ru-RU', {
year: 'numeric', month: 'short', day: 'numeric'
});
dates.map(d => dateFormatter.format(new Date(d)));
Intl.NumberFormat — числа и валюта
// Числа
new Intl.NumberFormat('ru-RU').format(1500000); // '1 500 000'
new Intl.NumberFormat('en-US').format(1500000); // '1,500,000'
// Валюта
new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB'
}).format(1500.5); // '1 500,50 ₽'
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(1500.5); // '$1,500.50'
// Проценты
new Intl.NumberFormat('ru-RU', {
style: 'percent',
minimumFractionDigits: 1
}).format(0.1567); // '15,7%'
// Компактный формат
new Intl.NumberFormat('ru-RU', { notation: 'compact' }).format(1500000); // '1,5 млн'
Intl.RelativeTimeFormat — относительное время
const rtf = new Intl.RelativeTimeFormat('ru-RU', { numeric: 'auto' });
rtf.format(-1, 'day'); // 'вчера'
rtf.format(1, 'day'); // 'завтра'
rtf.format(-3, 'hour'); // '3 часа назад'
rtf.format(2, 'week'); // 'через 2 недели'
rtf.format(-30, 'second'); // '30 секунд назад'
// Утилита «N единиц назад»
function timeAgo(date) {
const seconds = Math.floor((Date.now() - date) / 1000);
const units = [
[60, 'second'], [3600, 'minute'], [86400, 'hour'],
[604800, 'day'], [2592000, 'week'], [31536000, 'month']
];
for (const [limit, unit] of units) {
if (seconds < limit) {
return rtf.format(-Math.floor(seconds / (limit / 60)), unit);
}
}
return rtf.format(-Math.floor(seconds / 31536000), 'year');
}
Частые ошибки
- Месяц 0-based:
new Date(2026, 3, 10)— это 10 апреля (3 = апрель), а не 10 марта. - Мутация Date:
setDate,setMonthизменяют объект на месте — при вычислениях создавайте копию черезnew Date(original). - Создание форматтера в цикле:
new Intl.DateTimeFormat(...)дорого создавать. Выносите за пределы циклов. - Парсинг строк дат:
new Date('2026-04-10')интерпретирует как UTC полночь, аnew Date('2026-04-10T00:00:00')— как локальное время. Разница в часовом поясе может дать другой день.