bythe.net
← К ленте
Новинки

Temporal: JavaScript наконец получил нормальную работу с датами

Новый API заменяет объект Date, в котором месяцы считаются с нуля, а часовые пояса не существуют. Temporal доступен во всех основных браузерах без полифилов.

Что не так с Date

Объект Date был скопирован в 1995 году из Java, где его уже тогда считали неудачным. Месяцы нумеруются с нуля, дни недели с нуля, но дни месяца с единицы. Объект изменяемый, поэтому передать дату в функцию небезопасно. Часовой пояс только один, системный, и любая работа с другим поясом требует библиотеки. Разбор строк зависит от браузера.

Moment.js, date-fns, Luxon и Day.js десятилетиями закрывали эти дыры, и каждый проект тащил одну из них в бандл.

Что такое Temporal

Temporal, предложение для стандарта ECMAScript, разрабатывалось с 2017 года и достигло третьей стадии в 2021-м. Firefox включил его первым в 2025 году, Chrome и Safari догнали в течение следующего года. Осенью 2026-го API доступен в стабильных версиях всех основных браузеров и в Node.js.

Вместо одного объекта Date в Temporal несколько типов, и каждый отвечает за одно понятие:

  • Temporal.PlainDate — календарная дата без времени и пояса: день рождения, дедлайн.
  • Temporal.PlainTime — время дня без даты: ежедневный будильник.
  • Temporal.PlainDateTime — дата и время без пояса.
  • Temporal.ZonedDateTime — конкретный момент в конкретном часовом поясе.
  • Temporal.Instant — точка на временной шкале без пояса, как Unix-время.
  • Temporal.Duration — промежуток: «три дня и два часа».

Все объекты неизменяемы. Каждая операция возвращает новый объект.

Как это выглядит

const meeting = Temporal.ZonedDateTime.from(
"2026-10-20T15:00[Europe/Berlin]"
);
const inTokyo = meeting.withTimeZone("Asia/Tokyo");
const nextWeek = meeting.add({ weeks: 1 });
const until = Temporal.Now.zonedDateTimeISO().until(meeting);
console.log(inTokyo.hour); // 22
console.log(until.total("hours")); // часов до встречи

Разбор строк строго следует ISO 8601 с расширением для часовых поясов, и результат одинаков во всех реализациях. Арифметика учитывает переходы на летнее время: добавление суток к дате в день перевода часов даёт то, что ожидает человек, а не то, что ожидает счётчик миллисекунд.

Поддерживаются и другие календари: японский, исламский, еврейский, китайский. Для большинства проектов это не нужно, но раньше это было невозможно вовсе.

Что делать с существующим кодом

Date никуда не исчезнет: обратная совместимость в вебе священна. Для перехода есть методы toTemporalInstant() у Date и обратное преобразование. Библиотеки вроде date-fns уже предлагают адаптеры, а в новом коде смысла брать их больше нет.

Почему это важно

Ошибки с датами входят в тройку самых частых багов в прикладном коде. Temporal не делает их невозможными, но убирает целый класс: нулевые месяцы, мутации, потерянные часовые пояса. Через пару лет библиотеки для дат будут восприниматься так же, как полифилы для Promise.

Войти, чтобы оценить материал

Комментарии

Войти, чтобы оставить комментарий