Библиотека date-fns построена вокруг стандартного объекта
Date из JavaScript и не вводит собственный класс даты.
Основная идея — работа с нативными значениями времени через чистые
функции. В TypeScript библиотека предоставляет набор типов, дженериков и
вспомогательных интерфейсов, обеспечивающих строгую типизацию операций с
датами.
Во всех функциях библиотеки базовым типом остаётся стандартный объект:
Date
Пример:
import { addDays } from 'date-fns'
const date = new Date()
const result = addDays(date, 5)
Тип результата:
Date
Большинство функций принимают:
Date | number | string
Однако в TypeScript официально используется более строгая модель.
Во внутренних типах библиотеки используется обобщённый тип аргумента даты.
Условно его можно представить так:
type DateArg<DateType extends Date> =
| DateType
| number
| string
Он позволяет функциям принимать:
DateПример:
parseISO('2025-01-10')
fromUnixTime(1700000000)
new Date()
Одной из важных особенностей новых версий библиотеки стала поддержка пользовательских типов даты через дженерики.
Типичная сигнатура функции:
function addDays<
DateType extends Date,
ResultDate extends Date = DateType
>(
date: DateArg<DateType>,
amount: number,
options?: AddDaysOptions<ResultDate>
): ResultDate
Здесь:
DateType — тип входящей датыResultDate — тип возвращаемого значенияДженерики позволяют использовать расширенные классы дат.
Например:
class UTCDate extends Date {
isUTC = true
}
Теперь функции способны сохранять тип:
const utcDate = new UTCDate()
const result = addDays(utcDate, 3)
Тип результата:
UTCDate
Без дженериков был бы потерян пользовательский тип, а результатом
стал обычный Date.
Многие функции работают с интервалами времени.
Для этого используется тип:
Interval
Структура:
interface Interval {
start: Date
end: Date
}
Пример:
import { eachDayOfInterval } from 'date-fns'
const interval = {
start: new Date(2025, 0, 1),
end: new Date(2025, 0, 5),
}
const days = eachDayOfInterval(interval)
Тип Duration описывает длительность времени.
Структура:
interface Duration {
years?: number
months?: number
weeks?: number
days?: number
hours?: number
minutes?: number
seconds?: number
}
Пример:
import { add } from 'date-fns'
const result = add(new Date(), {
days: 5,
hours: 2,
})
Здесь объект соответствует типу Duration.
Все поля в Duration необязательны.
Допустимы конструкции:
{
days: 10
}
или:
{
minutes: 30
}
Это делает API гибким и удобным.
Для локализации используется тип:
Locale
Он описывает набор правил форматирования:
Пример:
import { format } from 'date-fns'
import { ru } from 'date-fns/locale'
format(new Date(), 'PPPP', {
locale: ru,
})
Тип ru:
Locale
Тип Locale достаточно большой.
Упрощённо:
interface Locale {
code?: string
formatDistance: Function
formatRelative: Function
localize: Object
formatLong: Object
match: Object
options?: Object
}
Некоторые функции поддерживают настройки недели.
Используется тип:
WeekOptions
Пример:
startOfWeek(date, {
weekStartsOn: 1,
})
Здесь:
weekStartsOn: number
означает день начала недели.
Для ISO-логики календаря используется:
FirstWeekContainsDateOptions
Пример:
getWeek(date, {
firstWeekContainsDate: 4,
})
Параметр определяет, какой день января обязан находиться в первой неделе года.
Многие функции используют композицию типов.
Например:
interface WeekOptions {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6
}
и:
interface FirstWeekContainsDateOptions {
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
Позже они объединяются:
type WeekStartOptions &
FirstWeekContainsDateOptions
Функция format использует большой набор настроек.
Пример:
format(date, 'yyyy-MM-dd', {
locale: ru,
useAdditionalWeekYearTokens: true,
})
Тип параметров:
FormatOptions
Для функции parse используется:
ParseOptions
Пример:
parse(
'2025-01-10',
'yyyy-MM-dd',
new Date(),
{
locale: ru,
}
)
Во внутренней реализации парсинга используются специальные карты валидации токенов.
Они контролируют:
Пример несовместимых токенов:
HH a
Поскольку:
HH — 24-часовой форматa — AM/PMВ системе локализации используется тип:
Matcher
Он отвечает за распознавание строк:
январь
понедельник
вчера
и преобразование их в значения даты.
Локализация формируется через специальные функции.
Пример:
type LocalizeFn<Value> = (
value: Value,
options?: LocalizeOptions
) => string
Используется для:
Внутренний тип эпох:
type Era = 0 | 1
Обычно:
0 -> BC
1 -> AD
Тип квартала:
type Quarter = 1 | 2 | 3 | 4
Используется в:
setQuarter()
getQuarter()
Тип месяца:
type Month =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
Соответствует JavaScript API.
Тип дня недели:
type Day =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
Используется функцией:
roundToNearestMinutes()
Пример:
roundToNearestMinutes(date, {
nearestTo: 15,
})
Тип:
interface NearestMinutesOptions {
nearestTo?: number
roundingMethod?: string
}
Некоторые функции поддерживают методы округления.
Пример:
differenceInHours(a, b, {
roundingMethod: 'ceil',
})
Допустимые значения:
'ceil'
'floor'
'round'
'trunc'
Используется функцией:
intervalToDuration()
Позволяет задавать настройки вычисления длительности.
Функция:
formatDistance()
использует:
FormatDistanceOptions
Пример:
formatDistance(date1, date2, {
addSuffix: true,
})
Для:
formatRelative()
используется:
FormatRelativeOptions
Некоторые функции ISO-форматирования поддерживают:
representation: 'complete'
representation: 'date'
representation: 'time'
Это часть типа:
ISOStringFormatOptions
Date-fns строго контролирует использование токенов форматирования.
Тип:
AdditionalTokensOptions
содержит:
useAdditionalWeekYearTokens
useAdditionalDayOfYearTokens
В новых версиях библиотеки появился контекст выполнения операций с датами.
Тип:
ContextOptions
используется для передачи дополнительной среды обработки даты.
Некоторые функции поддерживают ISO-недели.
Пример:
getISOWeek()
startOfISOWeek()
Связанные типы:
ISOWeekOptions
Большинство функций не принимают null и
undefined.
Например:
addDays(null, 5)
приведёт к ошибке типизации.
Это принципиальное отличие от многих старых библиотек.
Тип Date не гарантирует корректность даты.
Пример:
const date = new Date('wrong')
Тип:
Date
Но значение:
Invalid Date
Для проверки используется:
isValid(date)
Функция:
parseISO()
всегда возвращает:
Date
Даже если строка невалидна.
Пример:
const result = parseISO('abc')
Результат:
Invalid Date
Функции:
compareAsc()
compareDesc()
возвращают:
number
Возможные значения:
-1
0
1
Функции:
differenceInDays()
differenceInMonths()
возвращают:
number
Функции-предикаты возвращают:
boolean
Примеры:
isAfter()
isBefore()
isEqual()
isWeekend()
Функции генерации диапазонов возвращают:
Date[]
Пример:
const days = eachDayOfInterval({
start,
end,
})
Функции изменения компонентов даты:
setYear()
setMonth()
setDate()
возвращают новый объект:
Date
Исходная дата не мутируется.
Все функции библиотеки являются чистыми.
Пример:
const original = new Date()
const modified = addDays(original, 5)
Типы:
original -> Date
modified -> Date
При этом:
original !== modified
В модуле:
date-fns/fp
используется каррирование.
Пример:
import { addDays } from 'date-fns/fp'
const addFiveDays = addDays(5)
Тип функции:
(date: Date) => Date
Благодаря строгой типизации FP-версии хорошо работают с:
pipeflowПример:
const processDate =
flow(
addDays(5),
startOfMonth,
endOfWeek
)
Некоторые экосистемные расширения используют:
UTCDate
TZDate
Date-fns сохраняет совместимость благодаря дженерикам.
Пример:
class CustomDate extends Date {
timezone = 'UTC'
}
Использование:
const result = addHours(
new CustomDate(),
5
)
Результат сохраняет тип:
CustomDate
Хотя JavaScript допускает:
new Date('2025-01-01')
строковые даты часто приводят к:
Поэтому date-fns рекомендует:
parseISO()
Начиная с современных версий библиотеки токены:
YYYY
DD
считаются небезопасными.
Правильные варианты:
yyyy
dd
Типы и проверки помогают избежать ошибок миграции с Moment.js.
Timestamp представлен типом:
number
Пример:
fromUnixTime(1700000000)
или:
getTime()
Многие функции работают именно с миллисекундами.
Например:
addMilliseconds()
differenceInMilliseconds()
Все значения:
number
Базовая библиотека не содержит полноценного типа timezone.
Для этого используются дополнительные пакеты:
date-fns-tz@date-fns/utcВ расширении временных зон используются строковые идентификаторы:
'Asia/Almaty'
'Europe/Berlin'
'UTC'
Тип:
string
Функции расстояния между датами активно используют union-типы.
Например:
'lessThanXSeconds'
'xMinutes'
'aboutXHours'
Это позволяет локалям строго контролировать шаблоны текста.
Во внутреннем коде библиотеки используются:
Nullable<T>
DefaultOptions
LocalizedOptions
Они помогают строить гибкую архитектуру API.
Date-fns поддерживает глобальные default options:
setDefaultOptions({
weekStartsOn: 1,
})
Тип параметра:
DefaultOptions
Функция:
parseJSON()
возвращает:
Date
и поддерживает:
Функции:
isWithinInterval()
clamp()
используют:
Interval
Пример:
isWithinInterval(date, {
start,
end,
})
Некоторые API поддерживают строгие union-типы.
Например:
roundingMethod:
| 'ceil'
| 'floor'
| 'round'
| 'trunc'
Это исключает передачу произвольных строк.
Типизация библиотеки построена вокруг нескольких принципов:
DateТакой подход делает библиотеку удобной как для небольших приложений, так и для сложных enterprise-систем с глубокой типовой моделью времени и календарей.