Работа с датами и временем в JavaScript сопровождается множеством скрытых сложностей:
Библиотека date-fns предоставляет набор функций, позволяющих выполнять вычисления времени предсказуемо и безопасно.
В библиотеке существует важное разделение:
Например:
import { differenceInDays } from 'date-fns'
const start = new Date('2025-01-01')
const end = new Date('2025-01-10')
console.log(differenceInDays(end, start))
Результат:
9
Функция учитывает календарные сутки.
Однако существуют ситуации, когда разница должна измеряться строго по миллисекундам.
import { differenceInMilliseconds } from 'date-fns'
const start = new Date('2025-01-01T10:00:00')
const end = new Date('2025-01-01T10:00:01')
console.log(differenceInMilliseconds(end, start))
Результат:
1000
Функция возвращает строгое количество миллисекунд между двумя моментами времени.
import { differenceInSeconds } from 'date-fns'
const start = new Date('2025-01-01T10:00:00')
const end = new Date('2025-01-01T10:00:45')
console.log(differenceInSeconds(end, start))
Результат:
45
import { differenceInMinutes } from 'date-fns'
const start = new Date('2025-01-01T10:00:00')
const end = new Date('2025-01-01T10:42:00')
console.log(differenceInMinutes(end, start))
Результат:
42
import { differenceInHours } from 'date-fns'
const start = new Date('2025-01-01T08:00:00')
const end = new Date('2025-01-01T20:00:00')
console.log(differenceInHours(end, start))
Результат:
12
import { differenceInDays } from 'date-fns'
const start = new Date('2025-01-01')
const end = new Date('2025-01-15')
console.log(differenceInDays(end, start))
Результат:
14
import { differenceInWeeks } from 'date-fns'
const start = new Date('2025-01-01')
const end = new Date('2025-02-01')
console.log(differenceInWeeks(end, start))
import { differenceInMonths } from 'date-fns'
const start = new Date('2025-01-01')
const end = new Date('2025-06-01')
console.log(differenceInMonths(end, start))
Результат:
5
import { differenceInYears } from 'date-fns'
const start = new Date('2020-01-01')
const end = new Date('2025-01-01')
console.log(differenceInYears(end, start))
Результат:
5
JavaScript хранит дату как количество миллисекунд с 1 января 1970 года UTC.
Получение timestamp:
const date = new Date()
console.log(date.getTime())
В date-fns многие функции используют именно timestamp для точных вычислений.
import { addMilliseconds } from 'date-fns'
const now = new Date()
const result = addMilliseconds(now, 500)
import { addSeconds } from 'date-fns'
const now = new Date()
const result = addSeconds(now, 30)
import { addMinutes } from 'date-fns'
const now = new Date()
const result = addMinutes(now, 15)
import { addHours } from 'date-fns'
const now = new Date()
const result = addHours(now, 6)
import { addDays } from 'date-fns'
const now = new Date()
const result = addDays(now, 7)
import { subMinutes } from 'date-fns'
const now = new Date()
const result = subMinutes(now, 10)
import { subHours } from 'date-fns'
const now = new Date()
const result = subHours(now, 3)
import { subDays } from 'date-fns'
const now = new Date()
const result = subDays(now, 30)
Функция преобразует разницу между двумя датами в объект длительности.
import { intervalToDuration } from 'date-fns'
const start = new Date('2025-01-01')
const end = new Date('2025-03-15')
const duration = intervalToDuration({
start,
end
})
console.log(duration)
Результат:
{
months: 2,
days: 14
}
import { intervalToDuration, formatDuration } from 'date-fns'
const duration = intervalToDuration({
start: new Date('2025-01-01'),
end: new Date('2025-01-03')
})
console.log(formatDuration(duration))
Результат:
2 days
Unix timestamp хранится в секундах.
import { fromUnixTime } from 'date-fns'
const date = fromUnixTime(1735689600)
console.log(date)
import { getUnixTime } from 'date-fns'
const date = new Date()
console.log(getUnixTime(date))
import { differenceInMilliseconds } from 'date-fns'
const start = new Date()
for (let i = 0; i < 1000000; i++) {
Math.sqrt(i)
}
const end = new Date()
console.log(
differenceInMilliseconds(end, start)
)
import { isWithinInterval } from 'date-fns'
const target = new Date('2025-01-10')
const result = isWithinInterval(target, {
start: new Date('2025-01-01'),
end: new Date('2025-01-31')
})
console.log(result)
Результат:
true
При вычислениях часто требуется убрать секунды или миллисекунды.
import { startOfMinute } from 'date-fns'
const now = new Date()
console.log(startOfMinute(now))
import { startOfHour } from 'date-fns'
const now = new Date()
console.log(startOfHour(now))
import { startOfDay } from 'date-fns'
const now = new Date()
console.log(startOfDay(now))
import { roundToNearestMinutes } from 'date-fns'
const date = new Date('2025-01-01T10:07:00')
const rounded = roundToNearestMinutes(date, {
nearestTo: 5
})
console.log(rounded)
Результат:
10:05
import { max } from 'date-fns'
const result = max([
new Date('2025-01-01'),
new Date('2025-03-01'),
new Date('2025-02-01')
])
console.log(result)
import { min } from 'date-fns'
const result = min([
new Date('2025-01-01'),
new Date('2025-03-01'),
new Date('2025-02-01')
])
console.log(result)
import { isAfter } from 'date-fns'
const result = isAfter(
new Date('2025-02-01'),
new Date('2025-01-01')
)
console.log(result)
import { isBefore } from 'date-fns'
const result = isBefore(
new Date('2025-01-01'),
new Date('2025-02-01')
)
console.log(result)
import { isEqual } from 'date-fns'
const result = isEqual(
new Date('2025-01-01'),
new Date('2025-01-01')
)
console.log(result)
Стандартный объект Date использует локальный часовой
пояс системы, из-за чего вычисления могут отличаться на разных
серверах.
Для точных вычислений обычно применяются:
const date = new Date('2025-01-01T10:00:00Z')
Символ Z означает UTC.
Это позволяет избежать неоднозначностей локального времени.
Некоторые сутки могут содержать:
Из-за этого вычисление:
24 * 60 * 60 * 1000
не всегда эквивалентно одному календарному дню.
Поэтому:
addDays(date, 1)
предпочтительнее ручного прибавления миллисекунд.
import { addDays, addHours } from 'date-fns'
const date = new Date()
const a = addDays(date, 1)
const b = addHours(date, 24)
При переходе между часовыми поясами или во время DST результаты могут отличаться.
Рекомендуемые практики:
import {
differenceInSeconds,
intervalToDuration
} from 'date-fns'
const finish = new Date('2025-12-31T23:59:59')
setInterval(() => {
const now = new Date()
const seconds = differenceInSeconds(
finish,
now
)
const duration = intervalToDuration({
start: now,
end: finish
})
console.log(seconds)
console.log(duration)
}, 1000)
import {
isAfter,
addDays
} from 'date-fns'
const createdAt = new Date('2025-01-01')
const expiresAt = addDays(createdAt, 30)
const expired = isAfter(
new Date(),
expiresAt
)
console.log(expired)
import { differenceInYears } from 'date-fns'
const birthDate = new Date('1995-06-10')
const age = differenceInYears(
new Date(),
birthDate
)
console.log(age)
import {
differenceInMinutes,
differenceInSeconds
} from 'date-fns'
const login = new Date('2025-01-01T10:00:00')
const logout = new Date('2025-01-01T11:45:30')
console.log(
differenceInMinutes(logout, login)
)
console.log(
differenceInSeconds(logout, login)
)
const events = [
{ date: new Date('2025-03-01') },
{ date: new Date('2025-01-01') },
{ date: new Date('2025-02-01') }
]
events.sort(
(a, b) => a.date - b.date
)
console.log(events)