Предопределённые форматтеры

Библиотека js-joda предоставляет набор готовых форматтеров для преобразования объектов даты и времени в строки и обратно. Предопределённые форматтеры находятся в классе DateTimeFormatter и повторяют подход API java.time из Java.

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


Класс DateTimeFormatter

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

const { LocalDate, DateTimeFormatter } = require('@js-joda/core')

Пример использования:

const date = LocalDate.parse('2025-03-15')

const formatted = date.format(DateTimeFormatter.ISO_DATE)

console.log(formatted)

Результат:

2025-03-15

ISO-форматтеры

Большинство предопределённых форматтеров реализуют стандарт ISO-8601 — международный стандарт представления даты и времени.


ISO_LOCAL_DATE

Форматирует только дату без временной зоны.

Пример формата:

2025-07-21

Использование:

const { LocalDate, DateTimeFormatter } = require('@js-joda/core')

const date = LocalDate.of(2025, 7, 21)

console.log(
    date.format(DateTimeFormatter.ISO_LOCAL_DATE)
)

Результат:

2025-07-21

Такой форматтер работает только с локальной датой (LocalDate).


ISO_DATE

Похож на ISO_LOCAL_DATE, но может учитывать смещение зоны, если объект его содержит.

Пример:

const { OffsetDateTime, ZoneOffset, DateTimeFormatter } = require('@js-joda/core')

const dateTime = OffsetDateTime.of(
    2025,
    7,
    21,
    14,
    30,
    0,
    0,
    ZoneOffset.ofHours(3)
)

console.log(
    dateTime.format(DateTimeFormatter.ISO_DATE)
)

Результат:

2025-07-21+03:00

ISO_LOCAL_TIME

Используется для времени без даты и без временной зоны.

Пример:

const { LocalTime, DateTimeFormatter } = require('@js-joda/core')

const time = LocalTime.of(16, 45, 12)

console.log(
    time.format(DateTimeFormatter.ISO_LOCAL_TIME)
)

Результат:

16:45:12

ISO_TIME

Форматирует время с возможным указанием смещения.

Пример:

const { OffsetTime, ZoneOffset, DateTimeFormatter } = require('@js-joda/core')

const time = OffsetTime.of(
    16,
    45,
    12,
    0,
    ZoneOffset.ofHours(5)
)

console.log(
    time.format(DateTimeFormatter.ISO_TIME)
)

Результат:

16:45:12+05:00

ISO_LOCAL_DATE_TIME

Форматирует локальные дату и время без зоны.

Пример:

const { LocalDateTime, DateTimeFormatter } = require('@js-joda/core')

const dateTime = LocalDateTime.of(
    2025,
    7,
    21,
    18,
    10,
    45
)

console.log(
    dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
)

Результат:

2025-07-21T18:10:45

Символ T разделяет дату и время в ISO-формате.


ISO_DATE_TIME

Поддерживает дату, время и смещение временной зоны.

Пример:

const {
    ZonedDateTime,
    ZoneId,
    DateTimeFormatter
} = require('@js-joda/core')

const dateTime = ZonedDateTime.now(
    ZoneId.of('Europe/Moscow')
)

console.log(
    dateTime.format(DateTimeFormatter.ISO_DATE_TIME)
)

Возможный результат:

2025-07-21T18:15:42.381+03:00[Europe/Moscow]

ISO_OFFSET_DATE_TIME

Предназначен для объектов со смещением зоны (OffsetDateTime).

Пример:

const {
    OffsetDateTime,
    ZoneOffset,
    DateTimeFormatter
} = require('@js-joda/core')

const dateTime = OffsetDateTime.of(
    2025,
    1,
    10,
    9,
    30,
    15,
    0,
    ZoneOffset.ofHours(-2)
)

console.log(
    dateTime.format(
        DateTimeFormatter.ISO_OFFSET_DATE_TIME
    )
)

Результат:

2025-01-10T09:30:15-02:00

ISO_ZONED_DATE_TIME

Используется для объектов ZonedDateTime и включает идентификатор временной зоны.

Пример:

const {
    ZonedDateTime,
    ZoneId,
    DateTimeFormatter
} = require('@js-joda/core')

const zoned = ZonedDateTime.now(
    ZoneId.of('Asia/Tokyo')
)

console.log(
    zoned.format(
        DateTimeFormatter.ISO_ZONED_DATE_TIME
    )
)

Пример результата:

2025-07-22T00:10:00.215+09:00[Asia/Tokyo]

ISO_INSTANT

Форматирует момент времени в UTC.

Работает с объектом Instant.

Пример:

const {
    Instant,
    DateTimeFormatter
} = require('@js-joda/core')

const instant = Instant.now()

console.log(
    DateTimeFormatter.ISO_INSTANT.format(instant)
)

Пример результата:

2025-07-21T15:30:00.120Z

Суффикс Z означает нулевое смещение UTC.


BASIC_ISO_DATE

Компактный ISO-формат без разделителей.

Пример:

const {
    LocalDate,
    DateTimeFormatter
} = require('@js-joda/core')

const date = LocalDate.of(2025, 12, 5)

console.log(
    date.format(DateTimeFormatter.BASIC_ISO_DATE)
)

Результат:

20251205

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


RFC_1123_DATE_TIME

Форматтер для HTTP-заголовков и сетевых протоколов.

Пример:

const {
    ZonedDateTime,
    ZoneId,
    DateTimeFormatter
} = require('@js-joda/core')

const now = ZonedDateTime.now(
    ZoneId.of('UTC')
)

console.log(
    now.format(
        DateTimeFormatter.RFC_1123_DATE_TIME
    )
)

Пример результата:

Mon, 21 Jul 2025 15:40:00 GMT

Формат соответствует RFC 1123 и активно используется в HTTP.


Разница между LOCAL, OFFSET и ZONED

Предопределённые форматтеры тесно связаны с типами объектов времени.

Тип Содержит дату Содержит время Содержит смещение Содержит зону
LocalDate Да Нет Нет Нет
LocalDateTime Да Да Нет Нет
OffsetDateTime Да Да Да Нет
ZonedDateTime Да Да Да Да

Соответственно:

  • ISO_LOCAL_DATE_TIME не умеет работать с зоной
  • ISO_OFFSET_DATE_TIME требует смещение
  • ISO_ZONED_DATE_TIME содержит полную информацию о временной зоне

Парсинг строк с помощью предопределённых форматтеров

Форматтеры применяются не только для вывода строк, но и для разбора входящих данных.


Разбор даты

const {
    LocalDate,
    DateTimeFormatter
} = require('@js-joda/core')

const date = LocalDate.parse(
    '2025-08-11',
    DateTimeFormatter.ISO_LOCAL_DATE
)

console.log(date)

Разбор даты и времени

const {
    LocalDateTime,
    DateTimeFormatter
} = require('@js-joda/core')

const dateTime = LocalDateTime.parse(
    '2025-08-11T10:15:30',
    DateTimeFormatter.ISO_LOCAL_DATE_TIME
)

console.log(dateTime)

Разбор даты со смещением

const {
    OffsetDateTime,
    DateTimeFormatter
} = require('@js-joda/core')

const dateTime = OffsetDateTime.parse(
    '2025-08-11T10:15:30+03:00',
    DateTimeFormatter.ISO_OFFSET_DATE_TIME
)

console.log(dateTime)

Ошибки несовместимого формата

Если строка не соответствует формату, возникает исключение.

Пример:

const {
    LocalDate,
    DateTimeFormatter
} = require('@js-joda/core')

LocalDate.parse(
    '11-08-2025',
    DateTimeFormatter.ISO_LOCAL_DATE
)

Ошибка:

DateTimeParseException

Причина — форматтер ожидает строку вида:

2025-08-11

Автоматический выбор наносекунд

Многие ISO-форматтеры автоматически добавляют дробную часть секунд только при необходимости.

Пример:

const {
    LocalDateTime,
    DateTimeFormatter
} = require('@js-joda/core')

const dateTime = LocalDateTime.of(
    2025,
    7,
    21,
    12,
    30,
    15,
    123000000
)

console.log(
    dateTime.format(
        DateTimeFormatter.ISO_LOCAL_DATE_TIME
    )
)

Результат:

2025-07-21T12:30:15.123

Использование formatter.format()

У форматтера есть собственный метод format().

Пример:

const {
    LocalDate,
    DateTimeFormatter
} = require('@js-joda/core')

const formatter = DateTimeFormatter.ISO_LOCAL_DATE

const date = LocalDate.now()

console.log(
    formatter.format(date)
)

Результат аналогичен:

date.format(formatter)

Повторное использование форматтеров

Форматтеры являются неизменяемыми объектами (immutable).

Это означает:

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

Пример:

const {
    DateTimeFormatter
} = require('@js-joda/core')

const API_FORMATTER =
    DateTimeFormatter.ISO_OFFSET_DATE_TIME

Использование в REST API

ISO-форматтеры стали стандартом передачи даты и времени между сервисами.

Пример сериализации:

const {
    OffsetDateTime,
    ZoneOffset,
    DateTimeFormatter
} = require('@js-joda/core')

const createdAt = OffsetDateTime.now(
    ZoneOffset.UTC
)

const json = {
    createdAt: createdAt.format(
        DateTimeFormatter.ISO_OFFSET_DATE_TIME
    )
}

console.log(JSON.stringify(json, null, 2))

Результат:

{
  "createdAt": "2025-07-21T15:55:10.125Z"
}

Использование в логировании

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

Пример:

const {
    ZonedDateTime,
    ZoneId,
    DateTimeFormatter
} = require('@js-joda/core')

const timestamp = ZonedDateTime.now(
    ZoneId.of('UTC')
).format(
    DateTimeFormatter.ISO_ZONED_DATE_TIME
)

console.log(`[${timestamp}] Server started`)

Пример результата:

[2025-07-21T15:57:01.555Z[UTC]] Server started

Сравнение ISO_LOCAL_DATE и BASIC_ISO_DATE

Форматтер Пример
ISO_LOCAL_DATE 2025-07-21
BASIC_ISO_DATE 20250721

Первый вариант удобнее для чтения человеком, второй — компактнее.


Совместимость с JSON

Большинство современных API используют ISO-8601 как формат хранения времени в JSON.

Наиболее популярные варианты:

Форматтер Назначение
ISO_LOCAL_DATE Только дата
ISO_LOCAL_DATE_TIME Дата и время
ISO_OFFSET_DATE_TIME Дата, время, смещение
ISO_INSTANT UTC-время

Проверка корректности входящих данных

Предопределённые форматтеры позволяют валидировать строки даты и времени.

Пример:

const {
    LocalDate,
    DateTimeFormatter
} = require('@js-joda/core')

function isValidDate(value) {
    try {
        LocalDate.parse(
            value,
            DateTimeFormatter.ISO_LOCAL_DATE
        )

        return true
    } catch {
        return false
    }
}

console.log(isValidDate('2025-10-01'))
console.log(isValidDate('01.10.2025'))

Результат:

true
false

Основные предопределённые форматтеры

Форматтер Пример результата
ISO_LOCAL_DATE 2025-07-21
ISO_DATE 2025-07-21+03:00
ISO_LOCAL_TIME 18:30:00
ISO_TIME 18:30:00+03:00
ISO_LOCAL_DATE_TIME 2025-07-21T18:30:00
ISO_DATE_TIME 2025-07-21T18:30:00+03:00[Europe/Moscow]
ISO_OFFSET_DATE_TIME 2025-07-21T18:30:00+03:00
ISO_ZONED_DATE_TIME 2025-07-21T18:30:00+03:00[Europe/Moscow]
ISO_INSTANT 2025-07-21T15:30:00Z
BASIC_ISO_DATE 20250721
RFC_1123_DATE_TIME Mon, 21 Jul 2025 15:30:00 GMT