Date.now()

Date.now() – статический метод JavaScript, возвращающий число миллисекунд с 1 января 1970 года 00:00:00 UTC (Unix epoch). Вызывается без new и без создания объекта Date, поэтому быстрее new Date().getTime().

4 минуты чтения

Date.now() появился в ECMAScript 5 (2009) и с июля 2015 года поддерживается всеми современными браузерами (статус Baseline Widely available). Метод отвечает на один вопрос: сколько миллисекунд прошло от полуночи 1 января 1970 года по UTC (Unix epoch) до текущего момента. Такое число называют таймстемпом – универсальной меткой времени, которая не зависит от часового пояса и формата отображения. В прикладном коде таймстемпы встречаются повсюду: метки событий в логах и базах данных, ключи кэша, грубые замеры времени, контроль дрейфа таймеров setInterval.

Как это работает

Синтаксис предельно короткий: параметров нет, результат – число.

const ts = Date.now(); // например 1519211809934

// Unix-таймстемп в секундах
const unix = Math.floor(Date.now() / 1000);

Date.now() – статический метод класса Date: он вызывается только на самом классе. Записи вида myDate.now() или new Date.now() не сработают – метода now() у экземпляров просто нет. Объект Date при вызове не создаётся вовсе, и это главное практическое преимущество: в горячих участках кода (игровые циклы, частые обработчики) Date.now() отрабатывает быстрее, чем new Date().getTime(), и не оставляет мусора сборщику памяти.

Тот же таймстемп дают ещё три записи: new Date().getTime(), new Date().valueOf() и +new Date – унарный плюс приводит объект даты к числу. Значение у всех четырёх одинаковое, различается только цена вызова.

Date.now(), new Date().getTime() и performance.now() – в чём разница

Сравнение способов получить метку времени в JavaScript
СпособТочка отсчётаМонотонностьТочностьНазначение
Date.now()Unix epoch, UTCНет – читает системные часы1 мс (в Firefox – 2 мс)Таймстемпы событий, метки в логах и кэше
new Date().getTime()Unix epoch, UTCНет1 мсТо же, но с созданием лишнего объекта Date
+new DateUnix epoch, UTCНет1 мсКраткая запись getTime(); читается хуже
performance.now()timeOrigin – старт страницы или воркераДа – значение никогда не уменьшаетсяДробные мс (5–100 мкс после огрубления)Замеры длительности, профилирование

Ключевое отличие performance.now() – монотонные часы. Date.now() привязан к системному времени: если операционная система скорректировала часы по NTP или пользователь перевёл их вручную, разность двух вызовов может оказаться даже отрицательной. performance.now() от таких скачков не зависит: он возвращает дробные миллисекунды (тип DOMHighResTimeStamp) и отсчитывает их от Performance.timeOrigin – момента старта навигации в окне или запуска воркера. Абсолютное время без риска скачков даёт формула performance.timeOrigin + performance.now().

Про точность. Разрешение Date.now() – 1 миллисекунда: несколько вызовов подряд могут вернуть одно и то же значение. Браузеры дополнительно огрубляют таймеры для защиты от тайминг-атак и фингерпринтинга: в Firefox настройка privacy.reduceTimerPrecision включена по умолчанию, и результаты кратны 2 мс, а при включённом privacy.resistFingerprinting точность падает до 100 мс. У performance.now() механизм аналогичный: 5 микросекунд в cross-origin isolated контекстах и 100 микросекунд в обычных.

Зачем это нужно

Таймстемп – компактное число, которое однозначно сортируется, легко сравнивается и не требует парсинга. Отсюда типовые задачи:

  • Метки событий – зафиксировать момент действия пользователя для записи в лог или базу: число занимает меньше места, чем строка даты, и не зависит от локали.
  • Ключи кэша и версии данных – пометить ответ API или запись в localStorage временем создания, чтобы понимать, когда данные устарели. Метку последнего обновления виджета удобно класть в data-атрибут элемента.
  • Троттлинг обработчиков – ограничить частоту срабатывания тяжёлых обработчиков scroll или mousemove, в том числе при делегировании событий.
  • Контроль дрейфа таймеровsetInterval со временем «плывёт», и самокорректирующийся таймер сверяет фактическое время именно по Date.now().

Чего Date.now() не решает: длительности измеряют через performance.now() из-за монотонности, а для сложной работы с календарными датами нужен объект Date или новый стандарт Temporal API. Часовой пояс на Date.now() не влияет: таймстемп всегда считается по UTC. Пояс появляется только при форматировании – когда из числа делают объект new Date(ts) и выводят локальную дату.

Пример

Классический сценарий из документации MDN – грубый замер времени выполнения:

const start = Date.now();
doSomeLongRunningProcess();
console.log(`Прошло ${Date.now() - start} мс`);

Для коротких операций такой замер ненадёжен: шаг в 1–2 мс и зависимость от системных часов смазывают результат. Точный вариант – performance.now():

const t0 = performance.now();
doSomething();
const t1 = performance.now();
console.log(`Выполнение заняло ${t1 - t0} миллисекунд`);

А вот троттлинг обработчика скролла – задача, где Date.now() на своём месте: важна не точность, а дешевизна вызова.

let last = 0;
window.addEventListener("scroll", () => {
  const now = Date.now();
  if (now - last < 200) return; // не чаще 5 раз в секунду
  last = now;
  updateProgressBar();
});

Правило выбора простое: «который сейчас час» и метки событий – Date.now(); «сколько заняла операция» – performance.now().

Частые вопросы

Что возвращает Date.now() в JavaScript?

Число миллисекунд, прошедших с 1 января 1970 года 00:00:00 UTC (Unix epoch) до текущего момента. Метод не принимает параметров, результат имеет тип number. Метод статический: вызывается только как Date.now(), запись myDate.now() не сработает.

Чем Date.now() отличается от new Date()?

new Date() создаёт объект Date с методами форматирования и разбора дат, а Date.now() возвращает просто число – таймстемп. Объект при этом не создаётся, поэтому Date.now() быстрее и не нагружает сборщик мусора. Если нужна только метка времени, берите Date.now(); если нужно выводить дату – new Date().

Date.now() и new Date().getTime() – это одно и то же?

Семантически да: оба возвращают одинаковый таймстемп. То же значение дают new Date().valueOf() и +new Date (приведение даты к числу). Разница в цене: getTime() требует создать промежуточный объект Date, поэтому в коде, где важна производительность, предпочтителен Date.now().

Как получить Unix-таймстемп в секундах?

Разделить результат на 1000 и округлить вниз: Math.floor(Date.now() / 1000). Обратное преобразование – new Date(timestamp), где timestamp в миллисекундах; если исходник в секундах, его сначала умножают на 1000.

Когда использовать performance.now() вместо Date.now()?

Для замеров длительности: у performance.now() монотонные часы (значение никогда не уменьшается и не зависит от перевода системного времени) и дробные миллисекунды. Отсчёт идёт от Performance.timeOrigin – старта страницы, а не от Unix epoch. Date.now() оставьте для абсолютных меток времени.

Насколько точен Date.now()?

Базовое разрешение – 1 миллисекунда, поэтому несколько вызовов подряд могут вернуть одно значение. В Firefox точность намеренно снижена до 2 мс (настройка privacy.reduceTimerPrecision включена по умолчанию), а при privacy.resistFingerprinting – до 100 мс: это защита от тайминг-атак и фингерпринтинга. Кроме того, значение зависит от системных часов и может сдвигаться при NTP-коррекции.

Зависит ли Date.now() от часового пояса?

Нет. Таймстемп всегда отсчитывается от 1 января 1970 года по UTC, в любом поясе одновременный вызов даст одно и то же число. Часовой пояс влияет только на форматирование, когда из таймстемпа делают объект new Date(ts) и выводят локальные дату и время.

Материалы по теме

Валентина Меланина

Нужна консультация?

Разберу ваш сайт и покажу точки роста

Если хотите понять, как этот термин применить к вашему проекту — начнём с аудита.