Работа с датами и временем в TypeScript: от основ до продвинутых техник
Управление датами и временем — одна из ключевых задач в веб-разработке. Будь то отображение времени публикации, расчет дедлайнов или синхронизация данных с сервером, TypeScript предоставляет мощные инструменты для работы с временными метками. В этой статье мы разберем все аспекты работы с датами: от создания объекта Date до сложных манипуляций с часовыми поясами и форматирования.
1. Основы работы с объектом Date в TypeScript
В TypeScript, как и в JavaScript, за работу с датами отвечает встроенный объект Date. Благодаря строгой типизации, TypeScript помогает избежать ошибок при передаче некорректных данных.
Создание объекта Date
Существует несколько способов создать экземпляр даты:
// Текущая дата и время
const now: Date = new Date();
console.log(now); // Tue Oct 24 2023 14:30:00 GMT+0300
// По миллисекундам (Unix timestamp)
const fromTimestamp: Date = new Date(1698153000000);
// Из строки (ISO 8601)
const fromString: Date = new Date("2023-10-24T12:00:00Z");
// Из компонентов (год, месяц, день, часы, минуты, секунды)
const customDate: Date = new Date(2023, 9, 24, 14, 30, 0); // Месяцы от 0 до 11!
Важно: Месяцы в JavaScript/TypeScript нумеруются с 0 (январь — 0, декабрь — 11). Это частая причина багов.
Получение компонентов даты
Для извлечения отдельных частей даты используются геттеры:
const date: Date = new Date();
const year: number = date.getFullYear(); // 2023
const month: number = date.getMonth(); // 9 (октябрь)
const day: number = date.getDate(); // 24
const hours: number = date.getHours(); // 14
const minutes: number = date.getMinutes(); // 30
const seconds: number = date.getSeconds(); // 0
const dayOfWeek: number = date.getDay(); // 2 (вторник, 0 - воскресенье)
2. Форматирование и вывод дат
Стандартный вывод Date.toString() часто не подходит для пользовательских интерфейсов. Рассмотрим основные методы форматирования.
Встроенные методы форматирования
toDateString()— "Tue Oct 24 2023"toLocaleDateString()— локализованная дата (например, "24.10.2023" для России)toISOString()— строка в формате ISO ("2023-10-24T11:30:00.000Z")
const date: Date = new Date();
console.log(date.toLocaleDateString('ru-RU')); // 24.10.2023
console.log(date.toLocaleTimeString('ru-RU')); // 14:30:00
Кастомное форматирование с помощью Intl.DateTimeFormat
Для более гибкого контроля используйте Intl.DateTimeFormat:
const date: Date = new Date();
const formatter = new Intl.DateTimeFormat('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long',
hour: '2-digit',
minute: '2-digit'
});
console.log(formatter.format(date)); // "вторник, 24 октября 2023 г., 14:30"
Библиотека date-fns
Для сложных задач рекомендуется использовать библиотеку date-fns. Она легковесна и имеет отличную поддержку TypeScript:
import { format, addDays, isWeekend } from 'date-fns';
import { ru } from 'date-fns/locale';
const date: Date = new Date();
console.log(format(date, 'dd.MM.yyyy', { locale: ru })); // "24.10.2023"
console.log(format(date, 'HH:mm:ss')); // "14:30:00"
console.log(isWeekend(date)); // false
3. Манипуляции с датами: сложение, вычитание и сравнение
Изменение даты
Самый простой способ — использовать сеттеры:
const date: Date = new Date();
date.setFullYear(2024);
date.setMonth(11); // декабрь
date.setDate(31);
console.log(date); // "Tue Dec 31 2024 14:30:00"
Для работы с миллисекундами (что часто удобнее):
const date: Date = new Date();
const oneDayInMs: number = 24 * 60 * 60 * 1000;
const tomorrow: Date = new Date(date.getTime() + oneDayInMs);
const yesterday: Date = new Date(date.getTime() - oneDayInMs);
С date-fns это выглядит элегантнее:
import { addDays, subMonths, startOfWeek } from 'date-fns';
const today: Date = new Date();
const nextWeek: Date = addDays(today, 7);
const lastMonth: Date = subMonths(today, 1);
const monday: Date = startOfWeek(today, { weekStartsOn: 1 }); // понедельник
Сравнение дат
Даты можно сравнивать напрямую с помощью операторов >, <, === (для равенства используйте getTime()):
const date1: Date = new Date('2023-10-24');
const date2: Date = new Date('2023-10-25');
console.log(date1 < date2); // true
console.log(date1.getTime() === date2.getTime()); // false
Для более сложной логики используйте date-fns:
import { isBefore, isAfter, isSameDay, differenceInDays } from 'date-fns';
const start: Date = new Date('2023-10-01');
const end: Date = new Date('2023-10-31');
console.log(isBefore(start, end)); // true
console.log(isSameDay(start, new Date('2023-10-01'))); // true
console.log(differenceInDays(end, start)); // 30
4. Часовые пояса и работа с UTC
Одна из самых сложных тем — корректная работа с часовыми поясами. Всегда храните даты в UTC на сервере и конвертируйте в локальное время на клиенте.
Методы UTC
const date: Date =