Парсинг с указанием формата

Парсинг строк в Moment.js опирается на явное указание формата входных данных, что позволяет библиотеке интерпретировать дату и время предсказуемо и без неоднозначностей. Основной механизм реализуется через вызов moment(input, format) либо расширенную форму moment(input, format, strict).

При разборе строки Moment.js сопоставляет символы входной строки с токенами формата. Каждый токен описывает конкретную часть даты или времени:

  • YYYY — четырёхзначный год
  • YY — двухзначный год
  • MM — месяц (01–12)
  • DD — день месяца
  • HH — часы в 24-часовом формате
  • mm — минуты
  • ss — секунды

Строка анализируется последовательно, и каждое значение извлекается строго согласно позиции токенов.

const m = moment("2024-08-15", "YYYY-MM-DD");

В этом примере:

  • 2024 интерпретируется как год
  • 08 как месяц
  • 15 как день

Если структура строки не совпадает с форматом, результатом становится некорректная дата.

Токены формата и их поведение

Moment.js использует широкий набор токенов, позволяющий описывать практически любую текстовую дату:

Дата

  • D, DD — день месяца
  • Do — день месяца с порядковым суффиксом (1st, 2nd и т.д.)
  • M, MM — месяц
  • MMM, MMMM — сокращённое и полное название месяца

Время

  • H, HH — часы (24h)
  • h, hh — часы (12h)
  • a, A — am/pm
  • m, mm — минуты
  • s, ss — секунды

Полный пример формата

const m = moment("15-08-2024 14:30:00", "DD-MM-YYYY HH:mm:ss");

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

Строгий парсинг

Moment.js допускает два режима интерпретации: нестрогий и строгий. Строгий режим включается третьим параметром:

moment("2024-02-31", "YYYY-MM-DD", true);

В строгом режиме выполняется проверка:

  • соответствие длины сегментов
  • допустимость значений (например, месяц не больше 12)
  • корректность даты (например, февраль не может содержать 31 день)

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

moment("2024-02-31", "YYYY-MM-DD", true).isValid(); // false
moment("2024-02-31", "YYYY-MM-DD", false).isValid(); // true (но дата будет скорректирована)

Строгий режим критичен в системах, где требуется гарантия точности входных данных.

Парсинг с несколькими форматами

Moment.js поддерживает передачу массива форматов, что позволяет обрабатывать разные варианты входных строк:

const m = moment("15/08/2024", ["YYYY-MM-DD", "DD/MM/YYYY"]);

Алгоритм работает последовательно:

  1. проверяется первый формат
  2. при неудаче — следующий
  3. продолжается до первого успешного совпадения

Если ни один формат не подошёл, результат становится невалидной датой.

Разделители и гибкость структуры

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

moment("2024|08|15", "YYYY|MM|DD");

Поддерживаются:

  • пробелы
  • дефисы
  • точки
  • произвольные символы (/, |, :, ,)

Важно, что структура строки должна полностью соответствовать формату, включая все разделители.

Особенности интерпретации двухзначного года

Токен YY преобразуется в полный год по правилу окна (windowing):

  • 00–68 → 2000–2068
  • 69–99 → 1969–1999
moment("85-05-20", "YY-MM-DD"); // 1985-05-20

Это поведение важно учитывать при работе с историческими данными.

Часовые пояса при парсинге

Moment.js в базовой конфигурации не интерпретирует временные зоны из строки формата. Например:

moment("2024-08-15 10:00 +0300", "YYYY-MM-DD HH:mm Z");

Значение Z может быть распознано, но поведение зависит от подключённых расширений (например, moment-timezone). Без них смещение может игнорироваться или приводить к локальному времени.

Распространённые ошибки при парсинге

Несовпадение формата и строки

moment("2024/15/08", "YYYY-MM-DD").isValid(); // false

Причина — различие в порядке и разделителях.

Неполная строка

moment("2024-08", "YYYY-MM-DD").isValid(); // может быть true или некорректный результат

Недостающие части могут подставляться автоматически.

Нестрогий режим

moment("2024-13-99", "YYYY-MM-DD").isValid(); // true (исправляется автоматически)

Без строгого режима библиотека нормализует значения, что иногда приводит к неожиданным датам.

Приоритет форматов и неоднозначные строки

При использовании массива форматов выбор осуществляется по первому совпадению. Это может привести к неоднозначности:

moment("01-02-03", ["DD-MM-YY", "MM-DD-YY"]);

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

Парсинг текста с дополнительными символами

Moment.js позволяет разбирать строки, содержащие текстовые элементы:

moment("Сегодня 2024-08-15", "[Сегодня] YYYY-MM-DD");

Квадратные скобки фиксируют литеральные части, которые игнорируются при парсинге.

Поддерживаются конструкции:

  • фиксированный текст
  • повторяющиеся шаблоны
  • комбинирование текста и дат

Влияние локали на парсинг

При использовании названий месяцев или дней недели учитывается текущая локаль:

moment("15 août 2024", "DD MMMM YYYY");

Если локаль не соответствует языку строки, парсинг может не выполниться.

Локализация влияет на:

  • полные названия месяцев
  • сокращения
  • названия дней недели

Проверка результата парсинга

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

moment(input, format).isValid();

Дополнительно используются:

  • year(), month(), date() для проверки компонентов
  • format() для визуальной валидации результата
  • valueOf() для сравнения временных меток