Работа со временем в пользовательских интерфейсах неизбежно связана с временными зонами. Одно и то же значение времени может означать разные моменты в реальном мире в зависимости от географического региона. Поэтому интерфейсы, отображающие или принимающие дату и время, должны учитывать локальные настройки пользователя, стандарты хранения времени и правила преобразования между зонами.
Библиотека React Aria предоставляет инструменты для
создания доступных и корректно работающих компонентов ввода даты и
времени. Поддержка временных зон реализуется через интеграцию с
библиотекой @internationalized/date, которая содержит набор
структур и функций для работы с календарями, локалями и временными
зонами.
Использование специализированных объектов времени позволяет избежать
распространённых ошибок JavaScript, связанных с объектом
Date, например:
Для корректной работы с временными зонами React Aria использует несколько специализированных типов.
Объект даты без времени и без временной зоны.
import {CalendarDate} from '@internationalized/date';
let date = new CalendarDate(2026, 3, 16);
Характеристики:
Дата и время без привязки к временной зоне.
import {CalendarDateTime} from '@internationalized/date';
let dateTime = new CalendarDateTime(2026, 3, 16, 14, 30);
Особенности:
Дата и время с указанием временной зоны.
import {ZonedDateTime} from '@internationalized/date';
let dateTime = new ZonedDateTime(
2026,
3,
16,
"Europe/Berlin",
0,
14,
30
);
Содержит:
Этот тип является ключевым при работе с международными приложениями.
React Aria использует стандарт IANA Time Zone Database.
Примеры:
| Зона | Описание |
|---|---|
Europe/Berlin |
Центральная Европа |
America/New_York |
Восточное побережье США |
Asia/Tokyo |
Япония |
UTC |
Координированное мировое время |
Использование таких идентификаторов гарантирует корректную работу переходов на летнее время.
Определение временной зоны пользователя выполняется через функцию:
import {getLocalTimeZone} from '@internationalized/date';
let timezone = getLocalTimeZone();
Пример результата:
Europe/Paris
Asia/Almaty
America/Los_Angeles
Полученное значение используется при создании
ZonedDateTime.
Функция now() возвращает текущее время в указанной
зоне.
import {now, getLocalTimeZone} from '@internationalized/date';
let dateTime = now(getLocalTimeZone());
Тип результата:
ZonedDateTime
Это позволяет точно определить момент времени с учётом локальных правил.
Частая задача — отображение одного и того же момента времени для пользователей из разных регионов.
Для этого используется метод toTimeZone.
let berlinTime = dateTime.toTimeZone("Europe/Berlin");
let tokyoTime = dateTime.toTimeZone("Asia/Tokyo");
Исходный момент времени остаётся тем же, изменяется только отображение.
Когда пользователь вводит локальное время, оно не содержит информации о зоне. Поэтому необходимо преобразование.
import {toZoned} from '@internationalized/date';
let zoned = toZoned(dateTime, getLocalTimeZone());
Это добавляет:
React Aria предоставляет несколько компонентов, работающих с датой и временем:
DateFieldDatePickerDateRangePickerTimeFieldЕсли используется ZonedDateTime, компоненты
автоматически учитывают временную зону.
Пример DatePicker.
import {DatePicker} from 'react-aria-components';
import {now, getLocalTimeZone} from '@internationalized/date';
function Example() {
let value = now(getLocalTimeZone());
return (
<DatePicker value={value}>
{(state) => (
<>
<DateInput />
<Calendar />
</>
)}
</DatePicker>
);
}
Компонент отображает дату в соответствии с текущей зоной.
В большинстве приложений используется следующий подход:
Пример преобразования:
let utc = dateTime.toAbsolute();
Тип результата:
Instant
Этот формат независим от временных зон.
Когда данные получены с сервера:
import {fromAbsolute} from '@internationalized/date';
let localTime = fromAbsolute(instant, getLocalTimeZone());
Результат:
ZonedDateTime
Одной из сложнейших проблем является Daylight Saving Time (DST).
Пример:
В Европе перевод часов происходит:
В момент перехода некоторые значения времени могут:
Пример:
02:30
может быть:
Библиотека @internationalized/date учитывает эти
ситуации автоматически.
Если пользователь вводит время, которое не существует из-за DST, система корректирует значение.
Пример:
02:30 → 03:00
Это предотвращает ошибки.
Часто временные значения приходят из API в виде строки.
Пример ISO-формата:
2026-03-16T14:30:00+02:00[Europe/Berlin]
Парсинг выполняется следующим образом.
import {parseZonedDateTime} from '@internationalized/date';
let date = parseZonedDateTime(
"2026-03-16T14:30:00+02:00[Europe/Berlin]"
);
Для отображения времени используется
Intl.DateTimeFormat.
React Aria автоматически использует локаль пользователя.
Пример:
let formatter = new Intl.DateTimeFormat("ru-RU", {
dateStyle: "full",
timeStyle: "short",
timeZone: "Europe/Moscow"
});
Компонент TimeField позволяет вводить время.
import {TimeField} from 'react-aria-components';
import {parseTime} from '@internationalized/date';
function Example() {
let value = parseTime("14:30");
return (
<TimeField value={value}>
<DateInput />
</TimeField>
);
}
Если требуется поддержка временной зоны, используется
ZonedDateTime.
React Aria поддерживает выбор диапазонов.
<DateRangePicker
value={{
start: startDate,
end: endDate
}}
/>
Если значения являются ZonedDateTime, обе даты будут
находиться в одной временной зоне.
При сравнении необходимо использовать абсолютное время.
Неправильно:
date1.compare(date2)
Правильно:
date1.toAbsolute() === date2.toAbsolute()
Это гарантирует точность.
Для отправки на сервер обычно используется ISO-формат.
dateTime.toString()
Результат:
2026-03-16T14:30:00+02:00[Europe/Berlin]
Этот формат сохраняет:
Все события, происходящие в определённый момент времени (например,
видеоконференции), должны храниться как ZonedDateTime.
База данных должна хранить:
UTC timestamp
Это упрощает:
Преобразование временных зон должно происходить:
UTC → Local
непосредственно перед отображением.
Date в Jav * aScript:
Использование @internationalized/date устраняет эти
проблемы.
Типичная схема обработки времени:
Пользователь
↓
DatePicker / TimeField
↓
CalendarDateTime
↓
toZoned()
↓
ZonedDateTime
↓
toAbsolute()
↓
UTC (сервер)
Обратный путь:
UTC
↓
fromAbsolute()
↓
ZonedDateTime
↓
UI
Такой подход обеспечивает: