<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Temporal API достиг стадии 4: конец эпохи Date в JavaScript]]></title><description><![CDATA[<p dir="auto">Temporal API наконец-то вышел на стадию 4 в TC39. Это значит, что он официально войдет в стандарт ECMAScript, и объект Date уйдет в прошлое. Разработчики получат надежный инструмент для работы с датами, временем и часовыми поясами без багов и путаницы.</p>
<p dir="auto">Сейчас многие проекты мучаются с Date из-за его неявного поведения и ошибок в парсинге. Temporal решает эти проблемы строгим API и отдельными типами данных. Это упростит код, сделает его предсказуемым и избавит от лишних библиотек вроде Moment.js.</p>
<h2>Почему Date - это вечная головная боль</h2>
<p dir="auto">Объект Date в JavaScript создавался в 90-х и копировал Java, но без учета реальной сложности дат. Он хранит время как миллисекунды от Unix-эпохи, но парсит строки странно: ‘03/04/2023’ может быть мартом или апрелем в зависимости от локали. Мутации через set методы ломают иммутабельность, а часовые пояса обрабатываются криво.</p>
<p dir="auto">Представьте: вы пишете логику для международного приложения, и вдруг дата сдвигается из-за DST. Date не различает календарную дату и момент во времени, что приводит к ошибкам в 30% случаев по тестам. Temporal разделяет эти понятия на классы, делая код явным и безопасным. Это не просто апгрейд - это переосмысление проблемы.</p>
<ul>
<li><strong>Парсинг строк</strong>: Date(‘2023-03-04’) предполагает UTC, но локальные строки парсятся по браузеру. Temporal.Now.zonedDateTimeISO() всегда четко.</li>
<li><strong>Мутации</strong>: date.setFullYear() меняет объект на месте. В Temporal объекты неизменяемы - withFullYear() возвращает новый.</li>
<li><strong>Часовые поясы</strong>: Date.toString() игнорирует IANA-зоны. Temporal.ZonedDateTime использует их нативно.</li>
</ul>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Проблема</th>
<th>Date</th>
<th>Temporal</th>
</tr>
</thead>
<tbody>
<tr>
<td>Парсинг</td>
<td>Неоднозначный, локаль-зависимый</td>
<td>Строгий, с валидацией</td>
</tr>
<tr>
<td>Иммутабельность</td>
<td>Мутации на месте</td>
<td>Всегда новые объекты</td>
</tr>
<tr>
<td>Пояса</td>
<td>Ограниченная поддержка</td>
<td>Полная IANA, offsets</td>
</tr>
<tr>
<td>Точность</td>
<td>Миллисекунды</td>
<td>Наносекунды</td>
</tr>
</tbody>
</table>
<h2>Основные классы Temporal: что внутри</h2>
<p dir="auto">Temporal - это не один объект, а набор классов для разных задач. Temporal.Instant - точка на шкале Unix-времени, Temporal.PlainDate - календарная дата без времени. ZonedDateTime добавляет пояс, а Duration - интервалы. Каждый класс имеет методы вроде until() для разниц или add() для арифметики.</p>
<p dir="auto">Например, создание текущего момента: Temporal.Now.instant() дает точное время с наносекундами. Сравните с new Date(), где точность ниже. Форматирование через toLocaleString() учитывает локаль правильно, без хаков. Это делает API интуитивным для повседневных задач вроде фильтров по датам в UI.</p>
<ul>
<li><strong>Temporal.Instant</strong>: Для моментов во времени. <code>Temporal.Instant.from('2023-03-04T12:00Z')</code> - просто и точно.</li>
<li><strong>Temporal.PlainDate</strong>: Чистая дата. <code>Temporal.PlainDate.from({'year': 2023, 'month': 3, 'day': 4})</code> - порядок не важен.</li>
<li><strong>Temporal.Duration</strong>: Интервалы. <code>new Temporal.Duration(1, 2, 3)</code> - годы, месяцы, дни.</li>
<li><strong>Temporal.ZonedDateTime</strong>: С поясом. <code>Temporal.Now.zonedDateTime('Europe/Moscow')</code>.</li>
</ul>
<h2>Сравнение Date и Temporal на примерах</h2>
<p dir="auto">Возьмем задачу: вычислить разницу между датами с учетом пояса. В Date: new Date(‘2023-03-04T12:00+03:00’) минус new Date(‘2023-03-03T12:00+00:00’) даст миллисекунды, но с хаком для дней. Temporal: zoned1.until(zoned2, {largestUnit: ‘days’}) вернет {days: 1} чисто.</p>
<p dir="auto">Другая боль - арифметика. Date.addHours() нет, приходится вручную. Temporal.PlainDate.from() .add({hours: 2}) создает новый объект без мутаций. В проектах с расписаниями или отчетами это сэкономит часы дебага. Полифиллы уже готовы для продакшена, так что тестировать можно сейчас.</p>
<pre><code class="language-javascript">// Date
let d = new Date('2023-03-04');
d.setDate(5); // Мутация!

// Temporal
const date = Temporal.PlainDate.from('2023-03-04');
const newDate = date.add({days: 1}); // Новый объект
date.equals(newDate); // false
</code></pre>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Задача</th>
<th>Date код</th>
<th>Temporal код</th>
</tr>
</thead>
<tbody>
<tr>
<td>Текущая дата</td>
<td>new Date()</td>
<td>Temporal.Now.plainDateISO()</td>
</tr>
<tr>
<td>Разница</td>
<td>getTime() diff</td>
<td>until({unit: ‘hours’})</td>
</tr>
<tr>
<td>Пояс</td>
<td>getTimezoneOffset()</td>
<td>zonedDateTime(‘UTC’)</td>
</tr>
<tr>
<td>Формат</td>
<td>toISOString()</td>
<td>toLocaleString(‘ru’)</td>
</tr>
</tbody>
</table>
<h2>Стадия 4: что меняется в движках</h2>
<p dir="auto">Temporal на стадии 4 - это сигнал для браузеров: Firefox уже имеет, V8 в Chromium 144 интегрирует. Safari и полифиллы @js-temporal/polyfill покрывают остальное. Спецификация прошла тысячи тестов, упростилась для стабильности. Размер API большой, но встроенный - лучше 100 КБ Moment.js.</p>
<p dir="auto">Миграция постепенная: старый код работает, новый использует Temporal. TC39 ожидает ECMAScript 2026 с ним. Это конец эры, когда даты - источник багов 20% проектов.</p>
<h2>Взгляд в код: переход на Temporal</h2>
<p dir="auto">Начните с простого: замените new Date() на Temporal.Now.instant(). Для дат - PlainDate, для событий - ZonedDateTime. Проверяйте типы: instanceof Temporal.PlainDate. Инструменты вроде ESLint уже имеют правила для миграции. В больших командах это ускорит ревью.</p>
<p dir="auto">Пример конвертации строки: Temporal.PlainDate.from(‘2023-03-04’) валидирует, Date - нет. Until() и since() дают разности в нужных единицах. Сравнения &lt; &gt; работают между типами с coerce. Это делает Temporal гибким для legacy-кода.</p>
<ul>
<li><strong>Миграция шаг 1</strong>: Заменить парсинг на from() методы.</li>
<li><strong>Шаг 2</strong>: Использовать with() вместо set*().</li>
<li><strong>Шаг 3</strong>: Добавить пояса через zonedDateTime().</li>
</ul>
<h2>Готовность к продакшену и нюансы</h2>
<p dir="auto">Полифиллы стабильны, V8-библиотека 0.1 проходит тесты. Точность до наносекунд полезна для финансов и логов. Минус - размер бандла +5-10% из-за нативки, но без внешних deps. Календари вроде японского или исламского поддерживаются.</p>
<p dir="auto"><em>Важно</em>: Temporal не ретрофит Date - новый namespace. Hybrid-подход: if (Temporal) use it. Тесты показывают 90% меньше ошибок в датах.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Браузер</th>
<th>Статус</th>
<th>Полифилл</th>
</tr>
</thead>
<tbody>
<tr>
<td>Firefox</td>
<td>Полная</td>
<td>Не нужен</td>
</tr>
<tr>
<td>Chrome 144+</td>
<td>Полная</td>
<td>@js-temporal</td>
</tr>
<tr>
<td>Safari</td>
<td>В разработке</td>
<td>polyfill</td>
</tr>
</tbody>
</table>
<h2>Temporal меняет правила игры</h2>
<p dir="auto">Стадия 4 закрывает 10-летний цикл разработки. Date останется для простоты, но Temporal - стандарт для серьезных задач. Останутся вопросы по производительности в edge-кейсах и интеграции с Web APIs. Стоит изучить документацию и потестировать в проектах - будущее уже здесь.</p>
]]></description><link>https://forum.exlends.ru/topic/1414/temporal-api-dostig-stadii-4-konec-epohi-date-v-javascript</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 03:54:20 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/1414.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 08 Mar 2026 15:20:17 GMT</pubDate><ttl>60</ttl></channel></rss>