Temporal — долгожданная замена Date и moment.js, но она не делает магию, а лишь делает её предсказуемой. В production три сценария могут сломать логику: DST-разрывы, ложные сравнения и скрытые аллокации.
1. Граница дня — это не 24 часа: DST создаёт несуществующие моменты
Перевод часов в часовом поясе с летним временем — классическая ловушка. Попытка создать ZonedDateTime с несуществующим временем, например 02:30 в
America/New_York при переходе на DST:const zdt = Temporal.ZonedDateTime.from({
year: 2024, month: 3, day: 10,
timeZone: 'America/New_York',
hour: 2, minute: 30
}); // RangeError: момент не существуетРешение — опция
{ disambiguation: 'earlier' } или 'later'. Но 'later' даст 03:30 вместо ожидаемых 02:30. Логика с startOfDay() обязана это учитывать. Иначе баг воспроизводится раз в полгода.2. Сравнение ZonedDateTime: equals() игнорирует часовой пояс
equals() сравнивает календарные поля, а не абсолютное время:const a = Temporal.ZonedDateTime.from('2024-01-01[UTC]');
const b = Temporal.ZonedDateTime.from('2024-01-01[Asia/Tokyo]');
a.equals(b); // true — часы и даты совпадают, но момент разный
a.epochMilliseconds === b.epochMilliseconds; // false — физически разные моментыЭто ошибка: в
[UTC] и [Asia/Tokyo] один и тот же календарный день — это разные моменты, отстоящие на +9 часов. Для точного сравнения всегда приводите к Instant или используйте .since(). Иначе половина пользователей получит неверные расписания.3. Производительность: Temporal не бесплатен — профилируйте
Каждый
ZonedDateTime.from() с нестандартным часовым поясом парсит базу IANA TZif — это поиск по файлу. .until() / .since() не ленивы: сразу вычисляют разницу по всем полям. А toPlainDate() не кешируется — каждый вызов аллоцирует новый объект.На 100k+ событиях в секунду с разными таймзонами замена Date на Temporal дала рост CPU на 40% на Node.js 20. Для редких вычислений Temporal отличен, но для hot path используйте
Intl.DateTimeFormat + Date.getTime().Вывод: Temporal решает 90% старых проблем, но DST-разрывы, сравнение по календарю и неучтённые аллокации — ваши новые враги; профилируйте и тестируйте на границах дней с реальными данными.