Операции с миллисекундами

Миллисекунда — минимальная единица времени, с которой работает объект Date в JavaScript. Внутри любой даты хранится количество миллисекунд, прошедших с 1 января 1970 года 00:00:00 UTC — так называемая Unix Epoch.

Библиотека date-fns предоставляет набор функций для безопасной и удобной работы с такими значениями без мутаций исходных объектов.

Установка библиотеки:

npm install date-fns

Импорт отдельных функций:

import { addMilliseconds } from 'date-fns'

Добавление миллисекунд

Для прибавления миллисекунд используется функция addMilliseconds.

import { addMilliseconds } from 'date-fns'

const date = new Date(2025, 0, 1, 10, 0, 0)

const result = addMilliseconds(date, 1500)

console.log(result)
// 2025-01-01T04:00:01.500Z

Функция:

  • не изменяет исходный объект Date;
  • возвращает новый экземпляр даты;
  • автоматически учитывает перенос секунд, минут и часов.

Пример с переходом через секунду

const date = new Date(2025, 0, 1, 12, 30, 59, 900)

const result = addMilliseconds(date, 250)

console.log(result)
// 12:31:00.150

Вычитание миллисекунд

Для уменьшения времени применяется subMilliseconds.

import { subMilliseconds } from 'date-fns'

const date = new Date(2025, 0, 1, 12, 0, 0, 500)

const result = subMilliseconds(date, 800)

console.log(result)
// 11:59:59.700

Переход через границы времени

const date = new Date(2025, 0, 1, 0, 0, 0, 100)

const result = subMilliseconds(date, 200)

console.log(result)
// предыдущий день, 23:59:59.900

Получение количества миллисекунд

getMilliseconds

Функция возвращает миллисекундную часть времени.

import { getMilliseconds } from 'date-fns'

const date = new Date(2025, 0, 1, 12, 15, 30, 450)

console.log(getMilliseconds(date))
// 450

Диапазон значения:

0–999

Установка миллисекунд

Для изменения миллисекундной части используется setMilliseconds.

import { setMilliseconds } from 'date-fns'

const date = new Date(2025, 0, 1, 10, 20, 30, 100)

const result = setMilliseconds(date, 900)

console.log(result)
// миллисекунды станут 900

Автоматическое переполнение

JavaScript корректно обрабатывает значения больше 999.

const result = setMilliseconds(date, 1500)

Фактически это означает:

+1 секунда и 500 миллисекунд

Разница между датами в миллисекундах

differenceInMilliseconds

Функция вычисляет разницу между двумя датами.

import { differenceInMilliseconds } from 'date-fns'

const start = new Date(2025, 0, 1, 10, 0, 0)
const end = new Date(2025, 0, 1, 10, 0, 5)

const diff = differenceInMilliseconds(end, start)

console.log(diff)
// 5000

Отрицательные значения

const diff = differenceInMilliseconds(start, end)

console.log(diff)
// -5000

Это полезно для:

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

Сравнение с обычным вычитанием дат

В JavaScript можно вычитать даты напрямую:

const diff = end - start

Однако differenceInMilliseconds делает код:

  • более читаемым;
  • единообразным;
  • предсказуемым;
  • совместимым с другими функциями date-fns.
import { differenceInMilliseconds } from 'date-fns'

const diff = differenceInMilliseconds(end, start)

Преобразование даты в timestamp

getTime

Хотя это метод объекта Date, он активно используется вместе с date-fns.

const date = new Date()

console.log(date.getTime())

Результат:

1740000000000

Это количество миллисекунд с Unix Epoch.


Создание даты из timestamp

const timestamp = 1740000000000

const date = new Date(timestamp)

console.log(date)

Подобный подход применяется:

  • в базах данных;
  • REST API;
  • WebSocket;
  • системах логирования;
  • аналитике.

Проверка точности операций

Date-fns работает поверх стандартного объекта Date, поэтому точность ограничена возможностями JavaScript.

Минимальная единица:

1 миллисекунда

Микросекунды и наносекунды не поддерживаются стандартным 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)
)

Комбинация с addSeconds

Миллисекунды часто используются вместе с другими временными единицами.

import {
  addMilliseconds,
  addSeconds
} from 'date-fns'

const date = new Date()

const result = addMilliseconds(
  addSeconds(date, 10),
  500
)

Результат:

10.5 секунд вперёд

Округление времени

Для удаления миллисекунд часто используют setMilliseconds.

import { setMilliseconds } from 'date-fns'

const date = new Date()

const normalized = setMilliseconds(date, 0)

Это полезно:

  • при сравнении дат;
  • в SQL-запросах;
  • при сериализации;
  • в системах кеширования.

Проверка совпадения времени с точностью до миллисекунд

const a = new Date()
const b = new Date(a.getTime())

console.log(a.getTime() === b.getTime())
// true

Даже разница в одну миллисекунду изменит результат.


Таймеры и задержки

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

setTimeout

setTimeout(() => {
  console.log('Сработало')
}, 1500)

setInterval

setInterval(() => {
  console.log('Тик')
}, 250)

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


Форматирование миллисекунд

Стандартная функция format поддерживает вывод миллисекунд через шаблон SSS.

import { format } from 'date-fns'

const date = new Date(2025, 0, 1, 10, 20, 30, 125)

console.log(
  format(date, 'HH:mm:ss.SSS')
)

Результат:

10:20:30.125

Количество символов

Шаблон Результат
S 1
SS 12
SSS 125

Парсинг времени с миллисекундами

import { parse } from 'date-fns'

const date = parse(
  '10:20:30.250',
  'HH:mm:ss.SSS',
  new Date()
)

console.log(date)

Работа с Unix timestamp

fromUnixTime

Функция принимает секунды, а не миллисекунды.

import { fromUnixTime } from 'date-fns'

const date = fromUnixTime(1700000000)

Если имеется timestamp в миллисекундах:

const date = new Date(1700000000000)

Частая ошибка: секунды вместо миллисекунд

Неверно:

new Date(1700000000)

Результат будет датой 1970 года, потому что число интерпретируется как миллисекунды.

Правильно:

new Date(1700000000 * 1000)

Интервалы ожидания

Проверка истечения времени

import {
  differenceInMilliseconds
} from 'date-fns'

const createdAt = new Date()

setTimeout(() => {
  const now = new Date()

  const diff =
    differenceInMilliseconds(
      now,
      createdAt
    )

  console.log(diff)
}, 2000)

Дробные значения

Date-fns допускает дробные миллисекунды, но объект Date всё равно округляет значение.

addMilliseconds(date, 1.9)

Фактически:

≈ 2 миллисекунды

Работа с отрицательными значениями

addMilliseconds(date, -500)

Эквивалентно:

subMilliseconds(date, 500)

Использование в асинхронных системах

Миллисекунды критически важны для:

  • debounce;
  • throttle;
  • retry-механизмов;
  • очередей задач;
  • rate limiting;
  • heartbeat-сообщений.

Пример debounce

let lastCall = new Date()

function canCall() {
  const now = new Date()

  return (
    differenceInMilliseconds(
      now,
      lastCall
    ) > 300
  )
}

Измерение длительности операций

const start = Date.now()

fetch('/api/data')
  .then(() => {
    const end = Date.now()

    console.log(end - start)
  })

Date.now() возвращает timestamp в миллисекундах без создания объекта Date.


Date.now и new Date().getTime()

Эти конструкции почти эквивалентны:

Date.now()
new Date().getTime()

Но Date.now() работает быстрее, поскольку не создаёт объект даты.


Иммутабельность операций

Все функции date-fns возвращают новую дату.

const original = new Date()

const changed =
  addMilliseconds(original, 1000)

console.log(original === changed)
// false

Это уменьшает количество ошибок при работе со временем.


Композиция функций

Date-fns поддерживает функциональный стиль.

import {
  addMilliseconds,
  subMilliseconds
} from 'date-fns'

const result = subMilliseconds(
  addMilliseconds(new Date(), 5000),
  250
)

Практический пример: TTL кеша

import {
  addMilliseconds,
  isAfter
} from 'date-fns'

const createdAt = new Date()

const expiresAt =
  addMilliseconds(createdAt, 5000)

const expired =
  isAfter(new Date(), expiresAt)

console.log(expired)

Практический пример: вычисление ping

import {
  differenceInMilliseconds
} from 'date-fns'

const sentAt = new Date()

setTimeout(() => {
  const receivedAt = new Date()

  const ping =
    differenceInMilliseconds(
      receivedAt,
      sentAt
    )

  console.log(`${ping} ms`)
}, 120)

Практический пример: анимационный цикл

let previous = Date.now()

function update() {
  const current = Date.now()

  const delta =
    current - previous

  previous = current

  console.log(delta)

  requestAnimationFrame(update)
}

update()

delta показывает количество миллисекунд между кадрами.


Особенности часовых поясов

Миллисекунды всегда представляют абсолютное время. Проблемы возникают не в timestamp, а при отображении даты.

const timestamp = Date.now()

console.log(new Date(timestamp))

Один и тот же timestamp:

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

Проверка равенства дат

Нельзя сравнивать объекты Date напрямую.

Неверно:

date1 === date2

Правильно:

date1.getTime() === date2.getTime()

или:

differenceInMilliseconds(
  date1,
  date2
) === 0

Производительность

Date-fns работает быстрее многих крупных библиотек благодаря:

  • модульной архитектуре;
  • tree shaking;
  • отсутствию мутаций;
  • отсутствию глобального состояния.

При операциях с миллисекундами накладные расходы минимальны.


Основные функции для работы с миллисекундами

Функция Назначение
addMilliseconds Добавление миллисекунд
subMilliseconds Вычитание миллисекунд
differenceInMilliseconds Разница между датами
getMilliseconds Получение миллисекунд
setMilliseconds Установка миллисекунд
format Форматирование
parse Парсинг строки
isAfter Сравнение дат
Date.now Текущий timestamp