Firefox 139 — первый браузер с Temporal
Итак, официально: Firefox 139 станет первым браузером, который включает Temporal по умолчанию. Для JavaScript‑сообщества это важный рубеж. После почти трёх десятилетий с устаревшим Date
мы, наконец, получаем современную, надёжную и экспрессивную модель работы с датами и временем прямо «из коробки» браузера, а не через сторонние библиотеки.
Это событие — результат энтузиазма волонтёров и открытого процесса стандартизации: предложение Temporal
достигло Stage 3 TC39 в марте 2021 г., а уже через несколько недель в SpiderMonkey началась реализация. 99 патчей первоначального сета, сотни уточнений спецификации — и всё это во многом силами одного контрибьютора, André Bargull. История Temporal
напоминает: индивидуальный вклад всё ещё меняет ход развития веб‑платформы.
А что не так с Date
?
«Почему Date
так странно работает?» Пора признаться — потому что этот объект был спроектирован в 1995 году для браузера, который сегодня вспоминают только историки. Времена изменились: у нас глобальные приложения, распределённые базы данных и строгие требования к часовым поясам. Решать старые задачи новым способом нам помогает Temporal
.
Почему Date больше не справляется
Date
хранит внутреннее число миллисекунд и пытается угадать ваш часовой пояс. В итоге мы сталкиваемся с мутирующими методами, индексируемыми с нуля месяцами и вечным страхом «а что будет на переходе на летнее время?». Каждая библиотека тащит свои обёртки — dayjs
, date‑fns
— и всё равно остаётся чувство: «Это костыль, а не решение».
Что даёт Temporal разработчику
- Безопасность: нет неявных мутаций, все объекты неизменяемы.
- Читаемость: названия методов говорят сами за себя — add, since, withTimeZone.
- Детерминированность: никакой глобальной тайм‑зоны, всё явно.
- Мощная типизация (если вы используете TypeScript): разные классы для точки во времени, календарной даты, длительности.
Примеры использования Temporal
-
Локальное «сейчас» в ISO 8601
const now = Temporal.Now.plainDateTimeISO(); console.log(now.toString()); // 2025-04-18T14:43:17.123
-
Перевод события в часовой пояс пользователя
const releaseUTC = Temporal.ZonedDateTime.from('2025-05-12T16:00Z[UTC]'); const userZone = Temporal.Now.timeZone(); // 'Europe/Stockholm' const inUserTZ = releaseUTC.withTimeZone(userZone); console.log(inUserTZ.toString()); // 2025-05-12T18:00+02:00[Europe/Stockholm]
-
Сколько дней между двумя датами
const start = Temporal.PlainDate.from('2025-04-01'); const end = Temporal.PlainDate.from('2025-04-18'); const diff = end.since(start); console.log(diff.toString()); // P17D console.log(diff.days); // 17
-
Напоминание каждые две недели
const interval = Temporal.Duration.from({ weeks: 2 }); let next = Temporal.Now.plainDateISO(); for (let i = 0; i < 3; i++) { next = next.add(interval); console.log(`Следующая встреча: ${next.toString()}`); }
-
«Через месяц» без эффекта 31‑го числа
const invoiceDate = Temporal.PlainDate.from('2025-01-31'); const dueDate = invoiceDate.add({ months: 1 }, { overflow: 'constrain' }); console.log(dueDate.toString()); // 2025-02-28