Опции разбора

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

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


Общая структура опций

Почти все методы разбора поддерживают следующий шаблон:

  • DateTime.fromISO(text, options)
  • DateTime.fromSQL(text, options)
  • DateTime.fromRFC2822(text, options)
  • DateTime.fromFormat(text, format, options)
  • DateTime.fromMillis(ms, options)
  • DateTime.fromSeconds(sec, options)

Объект options может включать:

  • zone
  • setZone
  • locale
  • numberingSystem
  • outputCalendar

В некоторых случаях (например, fromFormat) добавляются специфические параметры, такие как strict.


Управление временной зоной через zone

Опция zone задаёт временную зону, в которой будет интерпретирована дата при разборе строки.

Пример поведения:

DateTime.fromISO("2026-05-23T10:00:00", { zone: "Europe/Moscow" })

Если строка не содержит явного смещения (например, Z или +03:00), Luxon будет считать, что время относится к указанной зоне.

Важный момент интерпретации

  • Если строка уже содержит временную зону, zone не переопределяет исходное значение
  • Для принудительного переопределения используется setZone

setZone: переопределение исходной зоны

Опция setZone изменяет поведение интерпретации входной строки, если в ней уже есть информация о временной зоне.

DateTime.fromISO("2026-05-23T10:00:00+03:00", {
  zone: "UTC",
  setZone: true
})

Поведение setZone:

  • setZone: false (по умолчанию):

    • Luxon использует зону из строки
    • параметр zone может влиять только на строки без зоны
  • setZone: true:

    • зона из строки сохраняется как есть
    • результат не нормализуется к zone

Практическое значение

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

  • логи серверов
  • события из разных регионов
  • импорт данных календарей

Локаль и форматирование при разборе

Опция locale влияет на интерпретацию текстовых компонентов даты, особенно при использовании fromFormat.

DateTime.fromFormat("23 мая 2026", "d MMMM yyyy", {
  locale: "ru"
})

Что меняется при смене локали

  • названия месяцев
  • названия дней недели
  • порядок и формат компонентов (в зависимости от шаблона)
  • правила разбора сокращений

Если локаль не указана, используется системная или глобальная настройка Luxon.


Номерная система (numberingSystem)

Опция numberingSystem определяет, какие символы используются для цифр.

DateTime.fromFormat("٢٣/٠٥/٢٠٢٦", "dd/MM/yyyy", {
  numberingSystem: "arab"
})

Поддерживаемые сценарии

  • арабские цифры (arab)
  • индийские системы (deva)
  • латинская система (latn)

Особенность

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


Календарная система (outputCalendar)

Опция outputCalendar управляет календарём, который используется внутри объекта DateTime.

DateTime.fromISO("2026-05-23", {
  outputCalendar: "islamic"
})

Основные варианты:

  • gregory (григорианский календарь)
  • islamic
  • buddhist
  • chinese

Важный нюанс

Календарь влияет не только на отображение, но и на внутренние вычисления дат. При этом ISO-строка остаётся входным стандартом, а календарь — способом представления результата.


Особенности fromFormat и дополнительные опции

Метод fromFormat является наиболее гибким и требует точного соответствия шаблону.

DateTime.fromFormat("23-05-2026 14:30", "dd-MM-yyyy HH:mm", {
  locale: "ru",
  zone: "Europe/Moscow",
  strict: true
})

strict: режим строгого разбора

Опция strict включает жёсткую проверку соответствия строки формату.

  • strict: true

    • строка должна полностью соответствовать шаблону
    • любые отклонения приводят к Invalid DateTime
  • strict: false (по умолчанию)

    • допускаются незначительные отклонения
    • Luxon может «достраивать» недостающие элементы

Поведение при отсутствующих компонентах

Если строка неполная, Luxon использует текущую дату как базу.

Пример:

DateTime.fromFormat("14:30", "HH:mm")

В этом случае:

  • дата берётся текущая
  • меняются только часы и минуты

При необходимости избежать такого поведения требуется явное управление базовыми значениями через дополнительные методы, например .set() после разбора.


Взаимодействие zone и locale

Комбинация zone и locale влияет на два разных уровня:

  • zone — физическое время (смещение, UTC)
  • locale — культурная интерпретация (форматы, текст)

Пример:

DateTime.fromISO("2026-05-23T10:00:00", {
  zone: "Asia/Tokyo",
  locale: "ru"
})

Здесь:

  • момент времени фиксируется в зоне Tokyo
  • отображение и форматирование будет русскоязычным

Обработка некорректных входных данных

Если разбор не удался, Luxon возвращает объект DateTime, помеченный как невалидный.

Проверка:

const dt = DateTime.fromFormat("invalid", "dd-MM-yyyy");

dt.isValid // false

Дополнительно доступны диагностические поля:

  • invalidReason
  • invalidExplanation

Типичные причины ошибок:

  • несовпадение формата (fromFormat)
  • неверная локаль
  • недопустимая временная зона
  • отсутствие обязательных компонентов даты

Приоритет опций при разборе

При конфликте параметров действует следующая логика:

  1. Явная зона в строке имеет приоритет над zone
  2. setZone: true сохраняет исходную зону строки
  3. locale влияет только на текстовые компоненты
  4. numberingSystem применяется до интерпретации чисел
  5. outputCalendar влияет на внутреннее представление результата

Нюансы работы с ISO и SQL форматами

fromISO

DateTime.fromISO("2026-05-23T10:00:00Z", options)
  • автоматически понимает Z
  • поддерживает миллисекунды
  • опции влияют только на интерпретацию, а не на синтаксис

fromSQL

DateTime.fromSQL("2026-05-23 10:00:00", options)
  • предполагает локальный формат без зоны
  • зона задаётся исключительно через options

Типичные ошибки при использовании опций

Ошибка 1: ожидание переопределения зоны

DateTime.fromISO("2026-05-23T10:00:00+03:00", {
  zone: "UTC"
})

Фактически:

  • зона строки сохраняется
  • zone не переписывает её без setZone

Ошибка 2: игнорирование locale при fromFormat

Если строка содержит текстовые месяцы, но не задан locale, разбор может быть некорректным или не выполниться вовсе.


Ошибка 3: смешивание numberingSystem и ASCII цифр

При несоответствии системы цифр входные данные могут выглядеть корректно, но не парситься.


Практическая модель применения опций

При проектировании систем разбора дат обычно выделяются три уровня управления:

  • Синтаксический уровень: формат строки (fromFormat, fromISO)
  • Культурный уровень: locale, numberingSystem
  • Временной уровень: zone, setZone, outputCalendar

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