Date.now()

ES5+

Returns the number of milliseconds elapsed since the ECMAScript epoch, January 1, 1970 00:00:00 UTC. It is a static method called directly on the Date constructor and returns a plain number, so no Date object is created. Because the value is always UTC-based, it is identical across time zones at any given instant.

Syntax

Date.now()

Return Value

number

A number representing the milliseconds elapsed since the UNIX epoch

Examples

JavaScript
console.log(Date.now());
// 성능 측정에 유용
const start = Date.now();
// ... 작업 수행
const end = Date.now();
console.log('소요 시간:', end - start, 'ms');
Output:
// 1705123456789 소요 시간: 5 ms

📌 When to Use

Use Date.now() whenever you need the current moment as a single comparable number: creating timestamps for log entries, marking when a cache entry was written so you can expire it later, implementing rate limiters and debounce logic, recording created-at fields before sending data to a server, or generating a rough uniqueness component for IDs. Because the return value is timezone-independent, it is the right choice for any value that will be stored, transmitted, or compared across machines: two computers in Seoul and New York calling Date.now() at the same instant get the same number. It is also the cheapest way to answer the question "how long did this take?" at millisecond granularity, by subtracting one reading from another. Prefer it over new Date().getTime() when you only need the number, since it skips object allocation entirely. Avoid it for two jobs it is not designed for: high-resolution benchmarking, where performance.now() offers sub-millisecond, monotonic readings that never jump backward, and security-sensitive token generation, where you need crypto.getRandomValues() instead of a predictable clock value. For calendar math such as adding a month, work with Date or Temporal objects rather than raw milliseconds.

⚠️ Common Mistakes

Writing new Date().getTime() or +new Date() when Date.now() gives the same number without allocating a throwaway Date object. All three return identical values, but the extra object churn is pure waste in hot paths such as game loops or scroll handlers, and the intent is less obvious to readers.

Measuring code performance with Date.now() and trusting small differences. The system clock is not monotonic: NTP synchronization, manual clock changes, or the OS suspending can make Date.now() jump forward or even backward mid-measurement, producing negative or wildly wrong durations. performance.now() is monotonic and made for this.

Using Date.now() alone as a unique ID. Two events in the same millisecond receive the same value, which happens constantly in loops, batch inserts, and concurrent requests. Combine it with a counter or random suffix, or use crypto.randomUUID() when real uniqueness matters.

Assuming the value is in seconds. Date.now() returns milliseconds, while many backends (Unix timestamps, JWT exp claims, some APIs) use seconds. Forgetting to divide or multiply by 1000 produces dates in the year 56138 or in 1970, a very common integration bug.

Expecting Date.now() to reflect the user's wall-clock time zone. It is a UTC-based offset; converting it into a local calendar date requires a Date object or Intl.DateTimeFormat. Comparing it directly to a "local midnight" computed by string manipulation invariably breaks across time zones.

✅ Best Practices

Store and transmit timestamps as the raw number that Date.now() returns (or its ISO string equivalent) instead of pre-formatted local strings. Numbers are compact, sortable, timezone-neutral, and can be re-rendered in any locale later with Intl.DateTimeFormat.

Use performance.now() for measuring durations inside a page or process: it is monotonic, unaffected by clock adjustments, and offers sub-millisecond resolution. Reserve Date.now() for wall-clock timestamps that must be meaningful outside the current session.

When converting between JavaScript milliseconds and Unix seconds, centralize the conversion in one helper (for example toUnixSeconds(ms)) so the divide-by-1000 logic exists in exactly one place and cannot silently disagree across the codebase.

For rate limiting and cache expiry, compare against a stored timestamp with subtraction (now - savedAt > ttl) rather than constructing Date objects; the arithmetic is simpler, faster, and immune to timezone concerns.

If your code will migrate to the Temporal API, Temporal.Now.instant() returns an immutable Instant with nanosecond precision that serializes cleanly; Date.now() remains fine as a lightweight bridge since Temporal.Instant.fromEpochMilliseconds(Date.now()) converts losslessly.

⚡ Performance Notes

Date.now() is one of the fastest ways to read the clock in JavaScript: engines compile it to a thin wrapper over the operating system clock call, and no Date object is allocated, so it produces zero garbage-collection pressure. In V8 microbenchmarks it is consistently faster than new Date().getTime() because the latter allocates an object only to read one field from it. That said, it is still a system call boundary, so calling it thousands of times inside a tight loop is wasteful; read it once per iteration or per frame and reuse the value. In browsers, timer precision may be slightly coarsened as a side-channel mitigation, but for wall-clock purposes the millisecond granularity is unaffected in practice. For sub-millisecond timing use performance.now(), which serves a different purpose (monotonic, high-resolution) at similar cost.

🌍 Real World Example

API Rate Limiter

A sliding-window rate limiter is a classic production use of Date.now(). Each permitted request records the current timestamp; before allowing a new request, the limiter discards timestamps older than the window and checks how many remain. Because everything is plain number arithmetic, the check is fast enough to run on every API call. The same pattern powers login-attempt throttling, notification batching, and client-side protection against accidental double-clicks on payment buttons.

class RateLimiter {
  constructor(maxRequests, timeWindowMs) {
    this.maxRequests = maxRequests;
    this.timeWindowMs = timeWindowMs;
    this.requests = [];
  }

  canMakeRequest() {
    const now = Date.now();
    // Remove expired timestamps
    this.requests = this.requests.filter(
      time => now - time < this.timeWindowMs
    );

    if (this.requests.length < this.maxRequests) {
      this.requests.push(now);
      return true;
    }
    return false;
  }
}

const limiter = new RateLimiter(5, 60000); // 5 requests per minute
console.log(limiter.canMakeRequest()); // true
console.log(limiter.canMakeRequest()); // true

Related Methods