Форматирование даты и времени

Библиотека date-fns предоставляет функциональный и предсказуемый набор инструментов для работы с датами в JavaScript. Основой форматирования выступает функция format, позволяющая преобразовывать объекты Date в строки по заданному шаблону.


Базовая функция форматирования format

Сигнатура:

format(date, formatString, [options])
  • date — объект Date или временная метка
  • formatString — строка шаблона
  • options — дополнительные параметры (локаль и др.)

Простейший пример:

import { format } from 'date-fns'

const now = new Date()

format(now, 'yyyy-MM-dd')
// 2026-05-22

Форматирование полностью определяется строкой шаблона, где каждая последовательность символов имеет специальное значение.


Основные токены форматирования

date-fns использует набор токенов, чувствительных к регистру. Это критически важно: MM и mm обозначают разные сущности.

Год, месяц, день

Токен Значение Пример
yyyy полный год 2026
yy последние 2 цифры года 26
M месяц (1–12) 5
MM месяц с ведущим нулём 05
MMM сокращённое название месяца May
MMMM полное название месяца May
format(new Date(), 'dd.MM.yyyy')
// 22.05.2026

День недели

Токен Значение Пример
E краткий день недели Fri
EEEE полный день недели Friday
format(new Date(), 'EEEE')
// Friday

Часы, минуты, секунды

Токен Значение Пример
HH часы (00–23) 14
hh часы (01–12) 02
mm минуты 07
ss секунды 09
a AM/PM PM
format(new Date(), 'HH:mm:ss')
// 14:35:09

Микс 12-часового формата

format(new Date(), 'hh:mm a')
// 02:35 PM

Форматирование с локализацией

date-fns поддерживает локали, которые влияют на названия месяцев и дней недели.

import { format } from 'date-fns'
import { ru } from 'date-fns/locale'

format(new Date(), 'EEEE, d MMMM yyyy', { locale: ru })
// пятница, 22 мая 2026

Локаль передаётся через опцию locale, что позволяет единообразно менять язык отображения без изменения шаблонов.


Работа с порядковыми числительными

Некоторые локали поддерживают порядковые суффиксы:

format(new Date(2026, 4, 22), "do MMMM")
// 22nd May (в en-US)

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

format(new Date(2026, 4, 22), "do MMMM", { locale: ru })
// 22 мая

Экранирование текста в шаблонах

Любой текст, не являющийся токеном, может быть интерпретирован как форматный символ. Для предотвращения этого используется экранирование:

format(new Date(), "'Дата:' dd.MM.yyyy")
// Дата: 22.05.2026

Символы внутри ' ' выводятся буквально.


Часто используемые шаблоны

ISO-подобный формат

format(new Date(), "yyyy-MM-dd'T'HH:mm:ss")
// 2026-05-22T14:35:09

Читабельная дата

format(new Date(), 'd MMMM yyyy')
// 22 May 2026

Полная дата и время

format(new Date(), 'EEEE, d MMMM yyyy HH:mm')
// Friday, 22 May 2026 14:35

Формат для логов

format(new Date(), 'yyyy/MM/dd HH:mm:ss')
// 2026/05/22 14:35:09

Особенности работы с месяцами и минутами

Одна из наиболее частых ошибок — путаница между:

  • MM — месяц
  • mm — минуты
format(new Date(), 'MM:mm')
// 05:35 (май и минуты)

Эта особенность связана с тем, что библиотека строго различает регистр символов.


Форматирование времени с учётом временных зон

Базовый format работает в локальной временной зоне окружения. Для явной работы с часовыми поясами используется date-fns-tz.

import { formatInTimeZone } from 'date-fns-tz'

const date = new Date()

formatInTimeZone(date, 'Europe/Moscow', 'yyyy-MM-dd HH:mm')
// 2026-05-22 17:35 (пример)

Это позволяет фиксировать отображение времени независимо от системной зоны.


Форматирование Unix timestamp

date-fns принимает timestamp как входное значение:

format(1684758909000, 'yyyy-MM-dd HH:mm')
// корректная обработка миллисекунд

Важно учитывать, что timestamp должен быть в миллисекундах, а не в секундах.


Вложенные сценарии форматирования

Генерация человекочитаемых строк

const date = new Date()

const result = format(date, "EEEE, d MMMM yyyy 'в' HH:mm")

Вывод:

Friday, 22 May 2026 в 14:35

Форматирование для UI-компонентов

const shortDate = format(date, 'dd.MM')
const fullDate = format(date, 'dd.MM.yyyy')
const time = format(date, 'HH:mm')

Разделение форматов позволяет переиспользовать данные без повторного создания Date.


Поведение при некорректных значениях

Если передано некорректное значение даты:

format(new Date('invalid'), 'yyyy-MM-dd')

результат будет Invalid Date. Это стандартное поведение JavaScript, не обрабатываемое автоматически библиотекой.


Производительность и повторное использование шаблонов

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

const FORMAT = 'yyyy-MM-dd HH:mm:ss'

dates.map(d => format(d, FORMAT))

Такой подход снижает накладные расходы при больших объёмах данных.


Комбинирование с другими функциями date-fns

Форматирование часто используется совместно с функциями:

  • parse — разбор строк в Date
  • addDays, subDays — арифметика дат
  • differenceInDays — вычисление интервалов
import { addDays, format } from 'date-fns'

format(addDays(new Date(), 7), 'yyyy-MM-dd')

Частые ошибки при форматировании

  • Использование YYYY вместо yyyy (различие в ISO-неделях)
  • Путаница mm и MM
  • Отсутствие экранирования текста
  • Игнорирование локали при интернационализации
  • Передача секунд вместо миллисекунд в timestamp

Особенности ISO-недели

Токен YYYY связан с ISO-неделями, а не календарным годом:

format(new Date('2026-12-31'), 'YYYY')
// может вернуть 2027

Для обычного календарного года используется:

format(date, 'yyyy')