Работа со множественными форматами

В реальных задачах обработки дат данные редко поступают в едином стандартизированном виде. Чаще встречаются смешанные представления: ISO-строки, локальные форматы, сокращённые записи, временные метки, а также пользовательские варианты. В таких условиях Day.js используется не как строгий парсер одного формата, а как слой нормализации входных значений.

Базовое поведение Day.js при разборе строки ограничено ISO-8601 и частично совместимыми форматами. Для расширенной обработки применяется плагин CustomParseFormat, позволяющий задавать набор допустимых шаблонов.


Подключение расширенного парсинга форматов

Для работы с множественными форматами требуется подключение плагина:

import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'

dayjs.extend(customParseFormat)

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


Разбор даты с массивом форматов

Ключевая возможность — передача массива шаблонов. Day.js последовательно проверяет каждый формат до первого успешного совпадения.

const dateStr = '12-03-2025'

const formats = [
  'YYYY/MM/DD',
  'DD-MM-YYYY',
  'MM-DD-YYYY'
]

const result = dayjs(dateStr, formats)

Механика работы:

  • входная строка сопоставляется с каждым форматом по порядку;
  • при первом совпадении выполняется парсинг;
  • остальные форматы игнорируются;
  • если совпадений нет, результат становится невалидным.

Строгий режим разбора

Для исключения неоднозначных интерпретаций используется строгий режим. Он запрещает частичное соответствие формату.

dayjs(dateStr, formats, true)

Особенности строгого режима:

  • формат должен совпадать полностью;
  • лишние символы приводят к невалидной дате;
  • упрощённые совпадения (например, 1/2 вместо 01/02) не принимаются;
  • повышается предсказуемость обработки данных.

Приоритет форматов и стратегия выбора

При использовании массива форматов порядок элементов становится значимым. Day.js не анализирует “наилучшее совпадение”, а использует первый успешный результат.

Пример:

const formats = [
  'MM/DD/YYYY',
  'DD/MM/YYYY'
]

В неоднозначных случаях (например, 01/02/2025) выбор формата зависит исключительно от порядка:

  • если первым стоит MM/DD/YYYY, интерпретация будет как 1 февраля;
  • если первым стоит DD/MM/YYYY, интерпретация будет как 1 января.

Это требует явного контроля при проектировании списка форматов.


Обработка разнотипных входных данных

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

  • ISO строки: 2025-03-12
  • европейский формат: 12.03.2025
  • американский формат: 03/12/2025
  • компактные записи: 20250312

Для унификации используется единый набор правил:

const formats = [
  'YYYY-MM-DD',
  'DD.MM.YYYY',
  'MM/DD/YYYY',
  'YYYYMMDD'
]

function parseDate(input) {
  const parsed = dayjs(input, formats, true)
  return parsed.isValid() ? parsed : null
}

Такой подход превращает Day.js в слой нормализации поверх неоднородных источников данных.


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

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

const d = dayjs(input, formats, true)

if (d.isValid()) {
  // корректная дата
} else {
  // некорректный формат или несоответствие шаблонам
}

Метод isValid() опирается на внутреннее состояние объекта и позволяет отфильтровывать нераспознанные значения.


Комбинирование форматов с локалями

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

import 'dayjs/locale/ru'
dayjs.locale('ru')

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


Форматирование результата в разные представления

После нормализации входной даты часто требуется вывести её в нескольких форматах одновременно.

const d = dayjs('2025-03-12', formats, true)

const outputs = {
  iso: d.format('YYYY-MM-DD'),
  readable: d.format('DD MMMM YYYY'),
  compact: d.format('YYYYMMDD')
}

Таким образом один объект даты служит источником для различных представлений без повторного парсинга.


Преобразование между форматами

Типичная задача — преобразование строки из неизвестного формата в строго заданный.

function convertDate(input) {
  const d = dayjs(input, formats, true)

  if (!d.isValid()) return null

  return d.format('YYYY-MM-DD')
}

Такой подход устраняет зависимость от исходного формата и приводит данные к единому стандарту хранения.


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

Некоторые входные строки могут соответствовать сразу нескольким форматам. В таких случаях используется стратегия:

  • приоритет формата по порядку;
  • либо предварительная детекция структуры строки;
  • либо сегментация по разделителям.

Пример простой детекции:

function detectFormat(str) {
  if (str.includes('-')) return 'YYYY-MM-DD'
  if (str.includes('/')) return 'MM/DD/YYYY'
  if (str.includes('.')) return 'DD.MM.YYYY'
  return 'YYYYMMDD'
}

Далее результат передаётся в Day.js:

dayjs(input, detectFormat(input), true)

Работа с массивами дат и смешанными источниками

При обработке коллекций данных применяется единый пайплайн:

const inputs = [
  '2025-03-12',
  '12.03.2025',
  '03/12/2025'
]

const normalized = inputs
  .map(i => dayjs(i, formats, true))
  .filter(d => d.isValid())
  .map(d => d.format('YYYY-MM-DD'))

Это обеспечивает унификацию независимо от исходного источника данных.


Ограничения при использовании множественных форматов

При работе с несколькими шаблонами важно учитывать особенности:

  • отсутствие автоматического выбора “наиболее вероятного” формата;
  • чувствительность к порядку массива;
  • необходимость строгого режима для критичных систем;
  • ограниченность неявной дедукции формата;
  • невозможность обработки полностью произвольных строк без предварительных правил.

Эти ограничения делают явное управление форматами обязательным элементом архитектуры обработки дат.


Формирование библиотеки форматов

В крупных системах набор форматов выделяется в отдельный модуль:

export const DATE_FORMATS = [
  'YYYY-MM-DD',
  'DD.MM.YYYY',
  'MM/DD/YYYY',
  'YYYYMMDD',
  'YYYY-MM-DDTHH:mm:ss'
]

Использование централизованного списка:

  • упрощает поддержку;
  • снижает риск несогласованности;
  • позволяет расширять правила без изменения логики парсинга;
  • обеспечивает единое поведение во всех частях приложения.

Композиция парсинга и форматирования

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

function normalize(input) {
  const d = dayjs(input, DATE_FORMATS, true)

  if (!d.isValid()) return null

  return {
    iso: d.format('YYYY-MM-DD'),
    timestamp: d.valueOf(),
    display: d.format('DD MMMM YYYY')
  }
}

Такая схема отделяет:

  • входные неоднородные данные;
  • внутреннее представление даты;
  • финальные представления для разных целей.

Стабильность преобразований в смешанных системах

При интеграции с внешними API, базами данных и пользовательскими интерфейсами многоформатный парсинг используется как промежуточный слой. Его задача — исключить зависимость бизнес-логики от конкретного формата представления даты и обеспечить детерминированное поведение при любых входных данных.