javascript

Temporal: 9-летний путь к исправлению времени в JavaScript

  • пятница, 13 марта 2026 г. в 00:00:10
https://habr.com/ru/articles/1009474/

Cтарший инженер-программист в организации JavaScript Infrastructure & Terminal Experience компании Bloomberg Джейсон Уильямс опубликовал пост, в котором рассказал, как он вместе с командой реализовывал библиотеку Temporal вместо Date для различных типов дат и времени. Автор выступает делегатом TC39 (группы экспертов из Ecma International, отвечающей за стандартизацию и развитие языка JavaScript) и имеет опыт стандартизации функций, реализации языка и участия в крупных проектах с открытым исходным кодом. Джейсон также является создателем движка Boa JavaScript.

Добро пожаловать в наш блог! Меня зовут Джейсон Уильямс, я старший инженер-программист в команде Bloomberg по инфраструктуре JavaScript и работе с терминалами. Сегодня терминал Bloomberg работает на JavaScript. Наша команда предоставляет среду JavaScript инженерам по всей компании.

Bloomberg, возможно, не первая компания, которая приходит вам на ум, когда речь заходит о JavaScript. Для меня это точно не было так в 2018 году, до того, как я начал здесь работать. Тогда я впервые посетил заседание TC39 в Лондоне, где познакомился с инженерами Bloomberg, которые обсуждали Realms, WebAssembly, поля классов и другие темы. Компания уже много лет занимается стандартизацией JavaScript, в том числе сотрудничает с Igalia. Среди предложений, в разработке которых мы принимали участие, можно отметить Arrow Functions, Async Await, BigInt, поля классов, Promise.allSettled, Promise.withResolvers, WeakRefs, стандартизацию Source Maps и многое другое!

Первое предложение, над которым я работал, называлось Promise.allSettled, и оно оказалось очень полезным. После его завершения я решил помочь с идеей, касающейся дат и времени, под названием Temporal.

Как меняется JavaScript?

JavaScript уникален тем, что он работает во всех браузерах. Нет единого «владельца», поэтому нельзя просто внести изменение изолированно и ожидать, что оно будет применяться везде. Необходимо согласие всех сторон. Эволюция происходит через TC39, технический комитет, ответственный за ECMAScript.

Предложения проходят ряд этапов зрелости:

  • Этап 0 — Идея.

  • Этап 1 — Проблема принята.

  • Этап 2 — Выбран черновой вариант дизайна, но работа продолжается.

  • Этап 2.7 — Предложение одобрено в принципе; ожидается тестирование и обратная связь.

  • Этап 3 — Реализация и обратная связь.

  • Этап 4 — Стандартизация.

В 2018 году, когда я впервые ознакомился с Temporal, проект находился на этапе 1. Комитет TC39 был убеждён в реальности проблемы. Это было радикальное предложение — внедрить в JavaScript совершенно новую библиотеку для работы с датами и временем. Она представляла собой:

  • замену для Date;

  • ресурс различных типов DateTime (вместо единого API);

  • идею неизменяемости;

  • гарант первоклассной поддержки часовых поясов и календаря.

Но как мы к этому пришли? Почему Date был таким проблемным моментом? Для этого нам нужно сделать шаг назад.

Продукт своего времени

В 1995 году Брендану Эйху было поручено за 10 дней создать Mocha (который позже стал JavaScript). В условиях строгих временных рамок многие проектные решения были прагматичными. Одним из них был прямой перенос реализации Date из Java. Как позже объяснил Брендан:

Это был прямой перенос кода Date из Java на C, выполненный Кеном Смитом (единственный код в Mocha, который я не писал).

В то время это имело смысл. Java был на подъёме, а JavaScript позиционировался как легковесный аналог. Внутри компании эта философия даже называлась MILLJ: Make It Look Like Java (Сделай так, чтобы это выглядело как Java).

Брендан также отметил, что изменение API было бы политически сложным:

Изменение его в то время, когда все ожидали, что Java станет языком «старшего брата», привело бы к путанице и ошибкам; Sun (Sun Microsystems — компания-разработчик языка) тоже возражала бы.

В тот момент согласованность с Java была важнее, чем фундаментальное переосмысление модели времени. Это был прагматичный компромисс. Веб был молод, и большинство приложений, использующих JavaScript, были бы простыми, по крайней мере, на начальном этапе.

Веб вырос, а Date — нет

К 2010-м годам JavaScript обеспечивал работу банковских систем, торговых терминалов, инструментов для совместной работы и других сложных систем, работающих во всех часовых поясах мира. Работа с датами становилась все большей проблемой для разработчиков.

Изменчивость

Разработчики часто писали вспомогательные функции, которые случайно изменяли исходный объект Date на месте, когда они намеревались вернуть новый:

const date = new Date("2026-02-25T00:00:00Z");
console.log(date.toISOString());
// "2026-02-25T00:00:00.000Z"

function addOneDay(d) {
  // oops! This is mutating the date
  d.setDate(d.getDate() + 1);
  return d;
}

addOneDay(date);

console.log(date.toISOString());
// "2026-02-26T00:00:00.000Z"

Непоследовательная арифметика месяцев

const billingDate = new Date("Sat Jan 31 2026");
billingDate.setMonth(billingDate.getMonth() + 1);
// Expected: Feb 28
// Actual:   Mar 02

Иногда люди хотят получить последний день месяца и попадают в ловушки, подобные этой, когда они сдвигают месяц на единицу, но дни остаются прежними. Date не преобразует недействительные результаты календаря обратно в действительную дату. Вместо этого он незаметно переносит переполнение в следующий месяц.

Неоднозначный синтаксический анализ

new Date("2026-06-25 15:15:00").toISOString();
// Potential Return Values:
// - local TimeZone
// - Invalid Date RangeError
// - UTC

В этом примере строка похожа, но не идентична ISO 8601. Исторически поведение браузеров для строк, «почти ISO», не было определено спецификацией. Некоторые обрабатывали их как местное время, другие как UTC, а один полностью выдавал ошибку как недействительный ввод.

Есть и другие проблемы, но суть в том, что Date был проблемным моментом для разработчиков JavaScript на протяжении последних трёх десятилетий.

Эпоха библиотек

Веб-экосистеме не оставалось ничего другого, как исправить недостатки Date с помощью библиотек. Ниже вы можете увидеть стремительный рост популярности библиотек для работы с датами и временем. Сегодня их скачивают более 100 миллионов раз в неделю.

Лидером в этом направлении стала библиотека Moment.js, которая может похвастаться выразительным API, мощными возможностями парсинга и столь необходимой неизменяемостью. Созданная в 2011 году, она быстро стала стандартом де-факто для обработки операций с датами и временем в JavaScript. Так что, очевидно, проблема решена? Всем просто нужно скачать её и на этом успокоиться.

Широкое распространение Moment.js (а также других подобных библиотек) сопровождалось последствиями. Добавление библиотеки означало увеличение размера пакета, поскольку её нужно было поставлять со своим собственным набором информации о локали, а также данными о часовых поясах из базы данных часовых поясов.

Несмотря на использование минификаторов, компиляторов и инструментов статического анализа, все эти дополнительные данные нельзя было удалить с помощью tree-shaking, потому что большинство разработчиков заранее не знают, какие локали или часовые пояса им понадобятся. Чтобы подстраховаться, большинство пользователей взяли все данные целиком и предоставили их своим пользователям.

Мэгги Джонсон-Пинт, которая была сопровождающей Moment.js в течение нескольких лет (наряду с другими), не понаслышке знала о просьбах решить проблему с размером пакета:

Мы дошли до того момента, когда поддержка модулей, webpack, требования к неизменяемости всего из-за React и т. д. стали более важными задачами, чем разработка новой функциональности.

И, конечно же, люди никогда не переставали говорить о размере пакета.

В 2017 году Мэгги решила, что пришло время стандартизировать даты и время, представив на пленарном заседании TC39 «Временное предложение». Оно было встречено с большим энтузиазмом, что привело к его продвижению на первый этап.

Чемпионы собираются

Первый этап стал важной вехой, но до финишной линии было ещё далеко. После первоначального всплеска энергии прогресс, естественно, замедлился. Мэгги и Мэтт Джонсон-Пинт возглавляли работу вместе с Брайаном Терлсоном, одновременно совмещая её с другими обязанностями в Microsoft. Временное предложение было ещё на ранней стадии, поэтому большая часть непосредственной работы была не слишком привлекательной: сбор требований, уточнение семантики и перевод «проблем экосистемы» в дизайн, который действительно можно было бы внедрить.

В Bloomberg эти проблемы не были теоретическими.

Мы запускаем JavaScript в масштабе всего терминала, используя базовые среды выполнения и движки, такие как Chromium, Node.js и SpiderMonkey. Наши пользователи и финансовые рынки, в которые они инвестируют, находятся во всех часовых поясах Земли. Мы постоянно передаём метки времени: между сервисами, в хранилище, в пользовательский интерфейс и между системами, которые должны согласовывать, что означает «сейчас», даже когда правительства меняют правила перехода на летнее время практически без предупреждения.

Кроме того, у нас были требования, для которых встроенная модель даты просто не была предназначена:

  • Настраиваемый пользователем часовой пояс, который не совпадает с часовым поясом машины (и может меняться по запросу).

  • Корректное поведение исторических часовых поясов, основанное на обновлениях базы данных часовых поясов IANA (tzdata).

  • Более точные метки времени (минимум наносекунды) без бесконечного добавления дополнительных полей к произвольным оболочкам.

Параллельно с тем, как Мэгги представила Temporal на TC39, инженер Bloomberg Эндрю Папроцки обсуждал с Igalia возможность настройки часовых поясов в V8. В частности, они обдумывали введение поддерживаемого уровня косвенного доступа, чтобы встраиваемый компонент мог контролировать «воспринимаемый» часовой пояс вместо того, чтобы полагаться на значение по умолчанию в ОС. В ходе той беседы Даниэль Эренберг (тогда работавший в Igalia) указал Эндрю на ранние разработки Temporal, поскольку они показались ему поразительно похожими на существующие в Bloomberg типы данных datetime, основанные на семантике значений.

Этот обмен мнениями стал своего рода мостом между производственными потребностями Bloomberg, опытом Igalia в области браузеров и стандартов и формирующимся направлением развития Temporal. В последующие годы Bloomberg сотрудничал с Igalia (включая постоянную финансовую поддержку) и напрямую вкладывал инженерное время в развитие Temporal, пока в конечном итоге она не стала продуктом, доступным для всей экосистемы. Эндрю искал добровольцев в Bloomberg, которые могли бы помочь продвинуть Temporal, и Филипп Дункель вызвался стать координатором проекта. Вместе с Эндрю он помог убедить Bloomberg инвестировать в реализацию Temporal, включая более тесное партнёрство с Igalia. Эта поддержка привлекла Филиппа Чименто и Уджвала Шарму в качестве штатных координаторов Temporal, обеспечив необходимую ежедневную поддержку для дальнейшего продвижения проекта.

Шейн Карр присоединился к Champions, представляя команду интернационализации Google. Он обеспечил необходимую нам фокусировку на вопросах интернационализации, таких как календари, а также выступил связующим звеном между процессом стандартизации и мнением пользователей, которые сталкивались с проблемами при работе с инструментами, связанными с API интернационализации JavaScript (Intl), такими как форматирование, часовые пояса и календари.

Наконец, к команде Temporal Champions в 2020 году присоединился Джастин Грант в качестве волонтёра. После 10 лет работы в трёх разных стартапах, занимавшихся обработкой данных с временными метками, он видел, как инженерные команды тратили тысячи часов на исправление ошибок с датами, временем и часовыми поясами. Опыт Джастина помог нам ориентироваться в реальных сценариях использования, предвидеть ошибки, которые могут допустить разработчики, и гарантировать, что Temporal выпустил API Temporal.ZonedDateTime, чтобы проблемы с переходом на летнее время остались в прошлом.

Среди других достойных упоминания лиц, не включённых в этот список, — Даниэль Эренберг, Адам Шоу и Кевин Несс.

Нынешние и бывшие чемпионы Temporal

  • Мэгги Джонсон-Пинт (Microsoft);

  • Мэтт Джонсон-Пинт (Microsoft);

  • Брайан Терлсон (Microsoft);

  • Ричард Гибсон (Agoric);

  • Филипп Дункель (Bloomberg);

  • Уджвал Шарма (Igalia);

  • Филип Чименто (Igalia);

  • Джейсон Уильямс (Bloomberg);

  • Шейн Карр (Google);

  • Джастин Грант (приглашённый эксперт).

Как выглядит Temporal сегодня

Temporal — это объект верхнего уровня пространства имен (подобный Math или Intl), существующий в глобальной области видимости. Под ним находятся «типы», которые существуют в виде конструкторов. Предполагается, что разработчики будут использовать нужный им тип при работе с API, например, Temporal.PlainDateTime.

Вот типы, которые поставляются с Temporal:

Temporal.ZonedDateTime

Если вы не знаете, какой тип Temporal вам нужен, начните с Temporal.ZonedDateTime. Это наиболее близкая концептуальная замена для Date, но без «подручных средств».

В Date:

  • точный момент времени (внутри системы — миллисекунды с начала эпохи);

  • интерпретируется через текущий часовой пояс машины;

  • с неявным, изменяемым поведением.

В Temporal.ZonedDateTime:

  • точный момент времени;

  • с явным указанием часового пояса;

  • с явным указанием календаря;

  • и полной корректностью с учётом перехода на летнее время;

  • всё это в виде неизменяемого значения.

Если вы сейчас пишете:

const now = new Date();

То вот эквивалент для Temporal:

const now = Temporal.Now.zonedDateTimeISO();

В приведённом выше примере используется пространство имен Now, которое предоставляет вам тип, уже настроенный на ваше текущее местное время и часовой пояс.

Этот тип оптимизирован для объектов DateTime, способных потребовать некоторых арифметических операций с датами и временем, в которых переход на летнее время потенциально может вызвать проблемы. ZonedDateTime может учитывать эти переходы при выполнении любых операций сложения или вычитания времени (см. пример ниже).

// London DST starts: 2026-03-29 01:00 -> 02:00
const zdt = Temporal.ZonedDateTime.from(
  "2026-03-29T00:30:00+00:00[Europe/London]",
);

console.log(zdt.toString());
// → "2026-03-29T00:30:00+00:00[Europe/London]"

const plus1h = zdt.add({ hours: 1 });

console.log(plus1h.toString());
// "2026-03-29T02:30:00+01:00[Europe/London]" (01:30 doesn't exist)

В этом примере мы попадаем не в 01:30, а в 02:30, потому что 01:30 в этот конкретный момент времени не существует.

Temporal.Instant

Temporal.Instant — это точный момент времени, он не имеет часового пояса, не использует летнее время и не имеет календаря. Он представляет собой прошедшее время с полуночи 1 января 1970 года (эпоха Unix). В отличие от Date, который имеет очень похожую модель данных, Instant измеряется в наносекундах, а не в миллисекундах. Это решение было принято разработчиками, потому что, хотя браузер и использует некоторую грубую обработку в целях безопасности, им всё равно приходится иметь дело с метками времени на основе наносекунд, которые могли быть сгенерированы из других источников.

Типичный пример использования Temporal.Instant выглядит так:

// One exact moment in time
const instant = Temporal.Instant.from("2026-02-25T15:15:00Z");

instant.toString();
// "2026-02-25T15:15:00Z"

instant.toZonedDateTimeISO("Europe/London").toString();
// "2026-02-25T15:15:00+00:00[Europe/London]"

instant.toZonedDateTimeISO("America/New_York").toString();
// "2026-02-25T10:15:00-05:00[America/New_York]"

Instant можно создать, а затем преобразовать в различные «зонированные» DateTime (подробнее об этом позже). Скорее всего, вы будете хранить Instant (в выбранном вами хранилище данных), а затем использовать различные преобразования часовых поясов, чтобы отображать одно и то же время пользователям в их часовых поясах.

Temporal.[PlainDate, PlainTime, PlainDateTime, PlainYearMonth, PlainMonthDay]

У нас также есть семейство простых типов. Это то, что мы называем «временем на стене», потому что, если представить аналоговые часы на стене, они не учитывают переход на летнее время или часовые пояса. Это просто обычное время (перевод стрелок вперёд на час продвинет его на час на циферблате, даже если это происходит во время перехода на летнее время).

У нас есть несколько типов с постепенно уменьшающимся объёмом информации. Это полезно, поскольку вы можете выбрать тип, который хотите представить, и вам не нужно беспокоиться о выполнении вычислений над любыми другими ненужными данными (например, вычислении времени, если вас интересует только отображение даты).

Эти типы также полезны, если вы планируете только отображать значение пользователю и вам не нужно выполнять какие-либо арифметические операции с датами/временем, например, перемещение вперёд или назад на недели (вам понадобится календарь) или часы (вы можете случайно пересечь границу перехода на летнее время). Ограничения некоторых из этих типов делают их такими полезными. Вам будет сложно ошибиться и столкнуться с неожиданными ошибками.

const date = Temporal.PlainDate.from({ year: 2026, month: 3, day: 11 }); // => 2026-03-11
date.year; // => 2026
date.inLeapYear; // => false
date.toString(); // => '2026-03-11'

Календари

Temporal поддерживает календари. Браузеры и среды выполнения поставляются с набором встроенных календарей, которые позволяют представлять, отображать и выполнять арифметические операции в предпочитаемой пользователем системе, а не просто по-другому форматировать григорианскую дату.

Поскольку объекты Temporal учитывают календари, такие операции, как «добавить один месяц», выполняются в соответствии с правилами этого календаря, поэтому вы получаете ожидаемый результат. В приведённом ниже примере мы добавляем один еврейский месяц к дате еврейского календаря:

const today = Temporal.PlainDate.from("2026-03-11[u-ca=hebrew]");
today.toLocaleString("en", { calendar: "hebrew" });
// '22 Adar 5786'

const nextMonth = today.add({ months: 1 });
nextMonth.toLocaleString("en", { calendar: "hebrew" });
// '22 Nisan 5786'

В устаревшей версии Date нет возможности выразить «добавить один еврейский месяц» как операцию первого класса. Вы можете использовать другой календарь для форматирования, но любые арифметические операции по-прежнему будут выполняться в соответствии с григорианским календарем.

Если бы вы попытались аппроксимировать это с помощью Date, это могло бы выглядеть так:

const legacyDate = new Date(2026, 2, 11);
legacyDate.toLocaleDateString("en", { calendar: "hebrew" });
// '22 Adar 5786'
legacyDate.setMonth(legacyDate.getMonth() + 1);
legacyDate.toLocaleDateString("en", { calendar: "hebrew" });
// '24 Nisan 5786'

Это добавляет один григорианский месяц (март → апрель). Когда вы затем отображаете результат в еврейском календаре, вы получаете другой день, 24 нисана, а не 22 нисана, потому что календари не имеют одинаковой структуры месяцев или их продолжительности.

Temporal.Duration

Наш последний тип — Temporal.Duration. Duration прост и может использоваться с любыми другими типами при сложении и вычитании. Ещё одна полезная функция Duration — отображение в разных единицах измерения, как в примере ниже:

const duration = Temporal.Duration.from({
  hours: 130,
  minutes: 20,
});

duration.total({ unit: "second" }); // => 469200

В большинстве библиотек для работы с датами и временем уже есть тип duration, поэтому это упростило использование.

Необходимо включить один из них. Он также дополняет другие типы, позволяя разработчику сравнивать Times или DateTimes и получать в ответ тип Duration.

Реализация

Реализация Temporal была сложной задачей. Это очень масштабное предложение, которое вносит больше изменений в JavaScript, чем любое другое предложение в истории языка программирования. Некоторые конкретные проблемы:

  • эта ГИГАНТСКАЯ спецификация больше, чем весь ECMA-402 (спецификация интернационализации); это затрудняло (но не делало невозможным) реализацию одним человеком;

  • изменчивость спецификации создавала постоянно меняющуюся цель. За эти годы в спецификацию вносились изменения, из-за чего реализациям было трудно успевать за ними;

  • браузеры требуют, чтобы почти все аспекты были эффективными и производительными.

Реализация Temporal была сложной задачей. Temporal — крупнейшее дополнение к ECMAScript со времён ES2015

Хотя Firefox смог реализовать Temporal в соответствии со спецификацией — благодаря замечательной работе Андре Баргулла (известного в сети как Anba) — не все браузеры или движки смогли работать с Temporal на ранних этапах. Это означает, что на более позднем 3-ем этапе потребовалось много времени, чтобы наверстать упущенное.

Temporal по количеству тестов, добавленных в официальный набор тестов для ECMAScript (Test262), является крупнейшим дополнением к спецификации ECMAScript. Сегодня Temporal содержит около 4500 тестов, что является большим числом по сравнению с некоторыми другими встроенными функциями, включая его предшественника, Date.

На пленарном заседании в июне 2024 года команда интернационализации Google и Boa решили сотрудничать в реализации Temporal и работать над библиотекой Rust, которая могла бы обслуживать оба движка. Библиотека называется temporal_rs. В течение 2024 и 2025 годов реализация Temporal была значительно расширена благодаря работе Кевина Несса, Маниша Горегаокара, Хосе Эспины и студентов из Университета Бергена. Сегодня temporal_rs проходит 100% всех тестов и теперь используется другими движками, помимо V8 и Boa!

temporal_rs — довольно нетрадиционный проект. Редко, если не беспрецедентно, чтобы несколько движков сотрудничали над общей библиотекой для реализации предложения TC39. Это не только сработало, но и имело огромный успех. temporal_rs обеспечил:

  • снижение порога входа: студентам и другим участникам не нужно было разбираться в коде V8 или Boa, чтобы внести свой вклад в библиотеку;

  • улучшенную долгосрочную поддержку: у temporal_rs есть команда разработчиков, которые продолжат работу над библиотекой даже после того, как Temporal достигнет 4-го этапа. Это обеспечивает разработчикам стабильное место для сообщения о проблемах, ошибок или даже внесения собственных улучшений при участии движков в качестве заинтересованных сторон;

  • более качественный код для проверки: поскольку temporal_rs позиционируется как библиотека, это означает, что её проверка стала проще, так как не требуется контекст всего движка. Кроме того, библиотека использует современные возможности Rust, такие как встроенная проверка синтаксиса (Clippy), форматирование (Rustfmt) и CI-тесты для движков.

Выпущено и стандартизировано

Ранее Temporal достиг 4-го этапа в процессе подготовки TC39, и это означает, что он будет частью следующей ежегодной спецификации ECMAScript (ES2026). Однако вам не нужно ждать этого — вы можете использовать его уже сегодня!

Поддержка Temporal уже реализована в следующих средах:

  • Firefox v139 (с мая 2025 г.)

  • Chrome v144 (с января 2026 г.);

  • Edge v144 (с января 2026 г.);

  • TypeScript 6.0 Beta (с февраля 2026 г.);

  • Safari (частичная поддержка в режиме предварительного просмотра);

  • Node.js v26 (уточняется).

Что дальше?

Для Temporal ещё предстоит выполнить много работы, например, разработать интеграцию с остальной веб-экосистемой. Веб-API уже много лет работают с объектом Date или вокруг него, и эти же API должны быть совместимы и с объектами Temporal. 

Вот несколько примеров:

Интеграция с элементами выбора даты

Разработчики захотят использовать Temporal с элементами выбора даты. Сейчас это невозможно (возможно, это можно исправить с помощью полифилла, но в стандарте на данный момент ничего подобного нет). По мере улучшения эргономики использования Temporal нам потребуется добавить поддержку в тех областях, где сегодня используется Date. Один из примеров — типы ввода, связанные с датой и временем. См. ниже:

<input type="date" />
<!-- element.valueAsPlainDate -->
<input type="time" />
<!-- element.valueAsPlainTime -->
<input type="week" />
<!-- element.valueAsPlainDate -->
<input type="month" />
<!-- element.valueAsPlainYearMonth -->

Дополнение DOMHighResTimeStamp

Благодаря тому, что Temporal Instant поддерживает время с точностью до наносекунд, его можно использовать везде, где используется DOMHighResTimeStamp. В следующем примере мы можем использовать Instant для установки срока действия cookie, тогда как раньше мы обычно использовали бы DOMHighResTimeStamp.

cookieStore.set({
  name: "foo",
  value: "bar",
  expires: Temporal.Now.instant().add({ hours: 24 }).epochMilliseconds,
});

И это ещё не все. Несомненно, сообщество JavaScript продолжит усердно работать над тем, чтобы Temporal был доступен не только для веб-платформы, но и для любых других библиотек, которые сегодня используют Date.

Лучшее время для JavaScript

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

  • годы ​​достижения консенсуса внутри TC39, основанного непосредственно на предыдущих разработках экосистемы;

  • работу по реализации в нескольких движках JavaScript;

  • сотрудничество между Microsoft, Google, Mozilla, Bloomberg, Igalia, Boa и многими независимыми участниками;

  • и редкий пример общей инфраструктуры в виде библиотеки temporal_rs.

Мы гордимся тем, что на протяжении многих лет финансировали и поддерживали работу Igalia над Temporal. Эти инвестиции в сочетании с открытым сотрудничеством успешно помогли продвинуть предложение от идеи к спецификации и к внедрению в реальность.

Успех temporal_rs демонстрирует нечто важное: новые языковые функции не обязательно означают дублирование усилий в разных движках. Общая, высококачественная инфраструктура с открытым исходным кодом может снизить затраты, повысить согласованность и ускорить инновации в веб-экосистеме.

Temporal — это не просто улучшенный API. Это доказательство того, что сообщество JavaScript способно вместе решать давние проблемы.

Спустя почти 30 лет в JavaScript наконец-то появился современный API для работы с датами и временем.

И на этот раз мы сделали всё правильно.