Данные о времени часто приходят в формате, который допускает несколько интерпретаций. Типичные источники неоднозначности:
01/02/03)При парсинге таких значений библиотека должна либо выбрать стратегию интерпретации, либо сигнализировать об ошибке.
В экосистеме js-joda эта задача решается через комбинацию форматтеров и правил разрешения неоднозначностей.
Основной вход в систему разбора — это методы parse у
типов даты и времени:
LocalDate.parseLocalDateTime.parseZonedDateTime.parseInstant.parseПростейший случай предполагает строго ISO-8601 формат:
LocalDate.parse("2026-05-25")
LocalDateTime.parse("2026-05-25T10:15:30")
ZonedDateTime.parse("2026-05-25T10:15:30+05:00[Asia/Almaty]")
ISO-парсинг не допускает неоднозначностей, поскольку формат строго определён.
На практике используются нестандартные представления:
25.05.2605/06/072026/05/25 10:1501-02-03Без явного шаблона такие строки не могут быть интерпретированы однозначно.
Для их обработки используется DateTimeFormatter.
Форматтер задаёт структуру входной строки:
const formatter = DateTimeFormatter.ofPattern("dd/MM/yy");
const date = LocalDate.parse("25/05/26", formatter);
Ключевая особенность — порядок компонентов фиксируется шаблоном. Это устраняет базовую неоднозначность.
Однако остаются ситуации, когда данные формально соответствуют шаблону, но допускают несколько трактовок:
При использовании шаблонов вида yy возникает
неопределённость:
25/05/26 → 1926 или 2026
js-joda применяет расширение года через базовое смещение, задаваемое форматтером:
const formatter = DateTimeFormatter
.ofPattern("dd/MM/yy")
.withDefaultYear(2026);
Если год интерпретируется как двухзначный, применяется окно преобразования:
00–99 → преобразование в полный годКлючевой механизм управления интерпретацией —
ResolverStyle.
Поддерживаются три режима:
Строгая проверка всех значений:
const formatter = DateTimeFormatter
.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
Поведение:
2026-02-31 → ошибка25/13/2026 → ошибкаКомпромиссный режим с логическими поправками:
.withResolverStyle(ResolverStyle.SMART);
Особенности:
Максимально свободная интерпретация:
Пример поведения:
2026-13-01 → январь 2027
Такой режим фактически превращает парсер в арифметический преобразователь дат.
Наиболее частая проблема — различие форматов:
dd/MM/yyyy (европейский стиль)MM/dd/yyyy (американский стиль)Строка:
01/02/2026
может означать:
js-joda не пытается угадывать формат. Интерпретация полностью
определяется DateTimeFormatter.
const euro = DateTimeFormatter.ofPattern("dd/MM/uuuu");
const us = DateTimeFormatter.ofPattern("MM/dd/uuuu");
LocalDate.parse("01/02/2026", euro);
LocalDate.parse("01/02/2026", us);
При разборе времени могут отсутствовать компоненты:
Пример:
LocalDateTime.parse("2026-05-25T10:15");
Если часть данных отсутствует, используются:
Часовые пояса создают отдельный класс проблем:
2026-05-25T10:00
2026-05-25T10:00Z
2026-05-25T10:00+05:00
Различия:
Z → UTCПри преобразовании в ZonedDateTime возникает
необходимость выбора зоны по умолчанию:
const zdt = LocalDateTime
.parse("2026-05-25T10:15")
.atZone(ZoneId.of("Asia/Almaty"));
Неоднозначность устраняется только явным указанием зоны.
При использовании SMART или LENIENT
возможны автоматические преобразования:
Пример логики:
2026-05-25T25:10 → 2026-05-26T01:10
Такое поведение особенно важно при обработке пользовательских форм.
Внутренний механизм js-joda использует концепцию resolver’а:
При конфликте полей:
Пример конфликтов:
При разборе:
DateTimeFormatter.ofPattern("e uuuu MM dd")
возможна ситуация, когда e (день недели) противоречит
dd/MM.
Решение зависит от режима:
Локаль влияет на:
DateTimeFormatter.ofPattern("d MMM uuuu")
.withLocale(Locale.FRANCE);
Строка:
25 mai 2026
интерпретируется корректно только при совпадении локали.
При несовпадении возникает неоднозначность или ошибка парсинга.
Ошибки в js-joda не являются побочным эффектом, а выступают механизмом защиты от неверной интерпретации.
Типичные причины:
При работе с внешними источниками данных применяются фиксированные стратегии:
DateTimeFormatterSTRICT для валидацииЭто снижает риск неоднозначной интерпретации до нуля за счёт явного описания формата.
В js-joda устранение неоднозначности достигается сочетанием трёх факторов:
DateTimeFormatterResolverStyleКаждый из них закрывает отдельный класс проблем: