В системе форматирования Luxon ключевым механизмом преобразования
объектов DateTime в строки выступает метод
toFormat. Он использует набор токенов (yyyy,
MM, dd, HH и т.д.), которые
интерпретируются как структурные элементы даты и времени. Любой текст,
не являющийся токеном, рассматривается как потенциальный литерал и
требует явного экранирования, чтобы не быть ошибочно распознанным как
часть форматной инструкции.
Литералы в форматной строке — это фиксированные фрагменты текста, которые должны быть выведены без изменений: пробелы, знаки препинания, слова, разделители. Без экранирования такие фрагменты могут конфликтовать с системой токенов, особенно если содержат символы, совпадающие с именами форматных директив.
При обработке строки формата Luxon выполняет последовательный разбор:
Проблема возникает в том, что часть обычных символов может быть
интерпретирована как управляющие конструкции. Например,
последовательность yyyy всегда трактуется как год, даже
если она является частью текстовой строки.
Наиболее читаемый и распространённый способ экранирования — использование квадратных скобок:
DateTime.now().toFormat("dd [декабря] yyyy")
Любой текст внутри [...] выводится буквально, без
анализа на токены.
[ и ] игнорируется парсером
токеновDateTime.now().toFormat("HH:mm [часов, зона:] ZZZZ")
Результат:
14:30 часов, зона: GMT+3
Квадратные скобки удобны для длинных текстовых вставок, особенно в локализованных форматах.
Второй механизм — использование одинарных кавычек:
DateTime.now().toFormat("dd 'декабря' yyyy")
Любой текст внутри кавычек трактуется как литерал.
Если внутри литерала требуется сам символ ', его
необходимо удваивать:
DateTime.now().toFormat("dd 'дня ''зимы''' yyyy")
Это создаёт сложные для чтения конструкции при частом использовании апострофов.
Апостроф в формате играет двойную роль: он обозначает начало и конец
литерала. Чтобы вставить сам символ ', применяется
удвоение:
DateTime.now().toFormat("yyyy 'год''а'")
Результат:
2026 года
Логика:
' закрывает литерал'' интерпретируется как один символ '' снова открывает или закрывает контекстТакая модель требует аккуратного построения строк при динамической генерации форматов.
Ключевая особенность системы заключается в том, что токены распознаются до обработки литералов. Это означает:
DateTime.now().toFormat("yyyy MM dd at HH:mm")
Без экранирования at не является проблемой, но если
используется конструкция вроде:
DateTime.now().toFormat("yyyy MM dd HHa")
a может быть интерпретировано как AM/PM токен, что
приведёт к искажению результата.
Корректная версия:
DateTime.now().toFormat("yyyy MM dd HH [at] a")
Оба способа экранирования могут использоваться совместно в одной строке:
DateTime.now().toFormat("dd [день] 'месяца' yyyy")
Логика применения:
При этом вложенность не поддерживается:
// некорректно
"dd ['месяц'] yyyy"
При использовании локализованных форматов литералы часто содержат грамматические связки:
DateTime.now().setLocale('ru').toFormat("d MMMM 'года'")
В этом случае:
MMMM зависит от локали'года' остаётся неизменнымДля англоязычных форматов аналогично:
DateTime.now().toFormat("MMMM d, yyyy 'at' HH:mm")
DateTime.now().toFormat("yyyy year MM month")
year и month могут интерпретироваться как
некорректные токены или игнорироваться.
DateTime.now().toFormat("yyyy 'year's end'")
Ошибка возникает из-за разрыва литерала.
Корректный вариант:
DateTime.now().toFormat("yyyy 'year''s end'")
DateTime.now().toFormat("yyyy [year's] end")
Здесь символ ' внутри скобок безопасен, но смешение
стилей ухудшает читаемость при сложных форматах.
В реальных сценариях формат может содержать одновременно дату, время и текстовые конструкции:
DateTime.now().toFormat(
"cccc, dd [декабря] yyyy 'года' в HH:mm:ss"
)
Разбор:
cccc — день неделиdd — день месяца[декабря] — фиксированное словоyyyy — год'года' — падежная формаHH:mm:ss — времяТакой подход позволяет создавать шаблоны, близкие к естественному языку, без потери структурной точности.
Выбор между квадратными скобками и кавычками определяется структурой строки:
При проектировании форматных шаблонов предпочтение обычно отдаётся квадратным скобкам как более предсказуемому и читаемому механизму, особенно в многоязычных приложениях.