Парсинг строк с обработкой ошибок

Работа с текстовым представлением дат и времени в js-joda строится вокруг строгой модели разбора, где любая строка интерпретируется через DateTimeFormatter, а результатом становится либо корректный объект времени, либо исключение DateTimeParseException. Такой подход делает систему предсказуемой и безопасной, исключая «тихие» ошибки интерпретации.


Базовый механизм разбора строк

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

  • LocalDate.parse
  • LocalTime.parse
  • LocalDateTime.parse
  • ZonedDateTime.parse
  • Instant.parse

Каждый из них использует либо стандартный формат ISO-8601, либо пользовательский форматтер.

import { LocalDate } from '@js-joda/core';

const date = LocalDate.parse('2026-05-25');

Строка должна строго соответствовать ожидаемому формату. Любое отклонение приводит к исключению.


Исключения при ошибках разбора

Основной тип ошибки при парсинге — DateTimeParseException. Он возникает при:

  • несоответствии формата строки
  • недопустимых значениях (например, 2026-02-30)
  • конфликте между строкой и форматтером
  • частично разобранных данных
import { LocalDate } from '@js-joda/core';

try {
  const date = LocalDate.parse('2026-02-30');
} catch (e) {
  console.log(e.name); // DateTimeParseException
}

Ошибка содержит полезные диагностические данные:

  • позицию, на которой произошёл сбой
  • ожидаемый символ или токен
  • исходную строку

Парсинг с использованием DateTimeFormatter

Гибкость достигается через DateTimeFormatter, позволяющий описывать произвольные форматы строк.

import { LocalDate, DateTimeFormatter } from '@js-joda/core';

const formatter = DateTimeFormatter.ofPattern('dd.MM.yyyy');

const date = LocalDate.parse('25.05.2026', formatter);

Любое отклонение от шаблона приводит к исключению, включая:

  • перестановку компонентов
  • лишние символы
  • пропущенные разделители

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

ResolverStyle определяет, насколько строго интерпретируется строка:

  • STRICT — полная проверка корректности даты
  • SMART — допускает некоторые логические исправления
  • LENIENT — максимально мягкая интерпретация
import { DateTimeFormatter, ResolverStyle } from '@js-joda/core';

const formatter = DateTimeFormatter
  .ofPattern('dd.MM.yyyy')
  .withResolverStyle(ResolverStyle.STRICT);

В строгом режиме невозможны несуществующие даты даже при корректном синтаксисе строки.


Разбор LocalDateTime и комбинированных форматов

LocalDateTime требует одновременного присутствия даты и времени.

import { LocalDateTime } from '@js-joda/core';

const dt = LocalDateTime.parse('2026-05-25T14:30:00');

При использовании кастомного формата важно учитывать разделитель T или его замену:

import { LocalDateTime, DateTimeFormatter } from '@js-joda/core';

const formatter = DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss');

const dt = LocalDateTime.parse('2026-05-25 14:30:00', formatter);

Отсутствие компонентов времени или даты приводит к ошибке полного разбора.


ZonedDateTime и обработка временных зон

Парсинг временных зон требует точного соответствия ISO или наличия зоны в формате.

import { ZonedDateTime } from '@js-joda/core';

const zdt = ZonedDateTime.parse('2026-05-25T14:30:00+05:00[Asia/Almaty]');

Ошибки возникают при:

  • отсутствии зоны при ожидании ZonedDateTime
  • некорректном ID временной зоны
  • конфликте смещения и зоны

Обработка ошибок через try/catch

Стандартная модель обработки ошибок базируется на перехвате исключений:

import { LocalDate } from '@js-joda/core';

function safeParseDate(str) {
  try {
    return LocalDate.parse(str);
  } catch (e) {
    if (e.name === 'DateTimeParseException') {
      return null;
    }
    throw e;
  }
}

Такой подход позволяет изолировать ошибки парсинга от остальной логики приложения.


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

Хотя js-joda не предоставляет встроенной функции «валидатора», предварительная проверка может снизить число исключений.

Типовые стратегии:

  • регулярные выражения для грубой фильтрации
  • проверка длины строки
  • контроль наличия разделителей
const isoDateRegex = /^\d{4}-\d{2}-\d{2}$/;

function parseDate(str) {
  if (!isoDateRegex.test(str)) return null;
  return LocalDate.parse(str);
}

Частичные форматы и Optional-поля

DateTimeFormatter поддерживает необязательные части через квадратные скобки:

import { DateTimeFormatter, LocalDateTime } from '@js-joda/core';

const formatter = DateTimeFormatter.ofPattern('yyyy-MM-dd['T'HH:mm:ss]');

const a = LocalDateTime.parse('2026-05-25', formatter);
const b = LocalDateTime.parse('2026-05-25T14:30:00', formatter);

Ошибки возникают, если обязательная часть отсутствует или нарушена структура скобок.


Типичные причины ошибок парсинга

На практике большинство сбоев связано с повторяющимися проблемами:

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

Диагностика DateTimeParseException

Исключение содержит структурированную информацию:

  • индекс ошибки в строке
  • описание ожидания парсера
  • исходный текст
try {
  LocalDate.parse('25-05-2026', DateTimeFormatter.ISO_DATE);
} catch (e) {
  console.log(e.getMessage());
}

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


Особенности поведения при неоднозначных форматах

Некоторые строки могут быть частично валидными, но неоднозначными:

  • 01/02/2026 — зависит от локали
  • 2026-05-25 00:00 — может требовать явного форматтера
  • 2026-05-25Z — интерпретация как UTC Instant

js-joda не пытается угадывать смысл строки, что исключает скрытые ошибки интерпретации.


Согласованность парсинга и сериализации

Строка, полученная через форматтер, должна обратно парситься тем же форматтером:

const formatter = DateTimeFormatter.ofPattern('dd.MM.yyyy');

const str = LocalDate.now().format(formatter);
const date = LocalDate.parse(str, formatter);

Несовпадение форматтеров приводит к нестабильному поведению и ошибкам в продакшн-логике.


Работа с ошибками в потоках данных

При обработке массивов строк применяется изоляция ошибок на уровне элемента:

const results = strings.map(s => {
  try {
    return LocalDate.parse(s);
  } catch {
    return null;
  }
});

Такой подход предотвращает остановку обработки всей коллекции при ошибке одного значения.


Граничные случаи парсинга

Особое внимание требуется при обработке:

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

js-joda строго применяет календарные правила, исключая невалидные комбинации независимо от контекста строки.