Стандарт ISO 8601

ISO 8601 представляет собой международный стандарт описания даты и времени, ориентированный на однозначность, машинную интерпретируемость и независимость от локальных форматов. В контексте JavaScript и библиотеки Day.js этот стандарт выступает базовым форматом для обмена временными данными между системами, API и хранилищами данных.

Ключевая особенность ISO 8601 — строгая структура строки даты и времени:

  • YYYY-MM-DD — календарная дата
  • YYYY-MM-DDTHH:mm:ss — дата и время
  • YYYY-MM-DDTHH:mm:ssZ — UTC-время
  • YYYY-MM-DDTHH:mm:ss+HH:mm — время с часовым смещением

Символ T разделяет дату и время, а Z обозначает нулевое смещение (UTC).


Внутренняя работа Day.js с ISO 8601

Day.js изначально поддерживает ISO 8601 без дополнительных плагинов. Это делает его удобным инструментом для работы с API, которые возвращают даты в стандартизированном формате.

Разбор ISO-строки:

import dayjs from 'dayjs';

const date = dayjs('2026-01-22T10:30:00Z');

В данном случае строка автоматически интерпретируется как UTC-время, несмотря на отсутствие явной настройки.

Если строка содержит смещение:

const date = dayjs('2026-01-22T10:30:00+05:00');

Day.js корректно учитывает смещение и преобразует время во внутреннее представление.


Формирование ISO 8601 строки

Одной из наиболее используемых операций является генерация ISO-строки из объекта Day.js.

const now = dayjs();
const iso = now.toISOString();

Метод toISOString() возвращает строку строго в формате UTC:

2026-01-22T08:15:30.000Z

Особенности:

  • всегда используется UTC (Z)
  • миллисекунды включены по умолчанию
  • результат соответствует стандарту ECMAScript Date.prototype.toISOString

Различие локального времени и UTC в ISO 8601

ISO 8601 допускает два ключевых представления:

  1. UTC-время
  2. Время с часовым смещением

Day.js при вызове toISOString() всегда приводит время к UTC, что важно учитывать при работе с локальными датами.

const local = dayjs('2026-01-22T10:00:00');
const iso = local.toISOString();

Если требуется сохранить локальное смещение, ISO 8601 формат должен формироваться иначе, с использованием плагина utc и timezone.


Работа с UTC и ISO 8601 через плагин utc

Для более строгого контроля над временными зонами применяется плагин utc.

import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);

const date = dayjs.utc('2026-01-22T10:00:00Z');

Создание ISO-строки в UTC-режиме:

const iso = date.utc().format();

Результат:

2026-01-22T10:00:00Z

Функция format() в сочетании с utc() позволяет фиксировать ISO-строку без локального смещения.


Структура ISO 8601 и допустимые вариации

ISO 8601 включает несколько уровней детализации:

Дата

2026-01-22

Дата и время

2026-01-22T10:30:00

Секунды с долями

2026-01-22T10:30:00.123

UTC

2026-01-22T10:30:00Z

Смещение

2026-01-22T10:30:00+03:00

Day.js корректно интерпретирует все перечисленные варианты, сохраняя внутреннюю нормализацию времени.


Парсинг ISO 8601 и строгая интерпретация

ISO 8601 является «родным» форматом для Day.js, поэтому базовый парсинг не требует дополнительных настроек:

const a = dayjs('2026-12-01T00:00:00Z');
const b = dayjs('2026-12-01T00:00:00+02:00');

Оба значения будут преобразованы в единую временную шкалу, что упрощает сравнение.

Сравнение дат:

a.isBefore(b);
a.isAfter(b);
a.isSame(b);

Ограничения базового парсинга ISO

Несмотря на поддержку ISO 8601, существуют нюансы:

  • неполные строки могут интерпретироваться неоднозначно
  • отсутствие времени трактуется как начало дня
  • локальное время зависит от окружения выполнения

Пример:

dayjs('2026-01-22')

Такое значение считается полуночью в локальной зоне.


ISO 8601 и форматирование через format()

Day.js предоставляет гибкий метод format(), но ISO 8601 требует строго определённого синтаксиса.

dayjs().format()

Без параметров результат будет ISO-подобным:

2026-01-22T10:30:00+03:00

Однако это не всегда строго UTC ISO-формат, поэтому для стандартного представления используется:

dayjs().toISOString()

Миллисекунды в ISO 8601

ISO 8601 допускает дробные секунды, и Day.js всегда включает миллисекунды при toISOString().

dayjs('2026-01-22T10:30:00.123Z').toISOString();

Результат:

2026-01-22T10:30:00.123Z

Если миллисекунды равны нулю, они всё равно отображаются:

2026-01-22T10:30:00.000Z

ISO 8601 и сравнение временных значений

ISO-строки удобны для сравнения, поскольку лексикографический порядок соответствует хронологическому при условии UTC.

const a = dayjs('2026-01-01T00:00:00Z');
const b = dayjs('2026-01-02T00:00:00Z');

a.isBefore(b);

Такая модель упрощает сортировку:

const sorted = [
  '2026-01-03T00:00:00Z',
  '2026-01-01T00:00:00Z',
  '2026-01-02T00:00:00Z'
].map(dayjs).sort((x, y) => x - y);

ISO 8601 в API и сериализации данных

ISO 8601 используется как универсальный формат передачи времени между клиентом и сервером.

Пример отправки:

const payload = {
  createdAt: dayjs().toISOString()
};

Получение:

const received = dayjs(payload.createdAt);

Отсутствие локальных смещений снижает вероятность ошибок при синхронизации систем.


Частичные форматы ISO и их интерпретация

Некоторые API используют частичные ISO-форматы:

  • только дата
  • только время (редко)
  • дата без зоны

Day.js интерпретирует их следующим образом:

dayjs('2026-01-22')        // начало дня
dayjs('2026-01-22T10:00')  // локальное время

При необходимости строгой обработки применяется customParseFormat, но для ISO-8601 это редко требуется.


ISO 8601 и временные зоны

Несмотря на наличие смещений в ISO, Day.js внутренне хранит время в UTC-эквиваленте.

dayjs('2026-01-22T10:00:00+03:00')

После парсинга значение приводится к единой временной шкале, что позволяет корректно сравнивать даты из разных зон.

При необходимости отображения локального времени используется плагин timezone.


Практическая структура ISO-данных в Day.js

Типичная работа с ISO в приложениях включает три операции:

  • получение текущего времени
  • сериализация в ISO
  • восстановление из ISO
const created = dayjs().toISOString();

const restored = dayjs(created);

const same = restored.isSame(dayjs(created));

Такой цикл обеспечивает стабильность хранения временных значений.


ISO 8601 и длительные интервалы времени

Хотя ISO 8601 в основном описывает моменты времени, он также поддерживает интервалы:

2026-01-01T00:00:00Z/2026-01-10T00:00:00Z

Day.js не имеет встроенного полноценного парсинга интервалов ISO 8601, поэтому такие строки обычно разбиваются вручную:

const [start, end] = range.split('/');
const startDate = dayjs(start);
const endDate = dayjs(end);

Влияние ISO 8601 на архитектуру приложений

Использование ISO 8601 в связке с Day.js формирует единый слой временной абстракции:

  • единый формат хранения
  • отсутствие неоднозначности локалей
  • упрощённая сериализация JSON
  • совместимость с REST и GraphQL API

Day.js выступает как промежуточный слой между строковым ISO-представлением и операциями над временем, обеспечивая предсказуемую нормализацию значений.