Performance timing
Wall-clock and monotonic timing grouped together, the way real JS/Node group them. Date follows the host's time zone as Node's does (local getters, the component constructor, toString), with Invalid Date for an unparseable string. A Date is an object, so `===` compares identity and a setter changes the one Date every reference sees; the remaining divergence is that a zone outside the built-in name table prints its abbreviation in toString. performance and perf_hooks are Node's own user-timing code ported to TypeScript: marks and measures are entries on a timeline, observers receive them on a later turn of the loop, and histograms time the event loop.
performance.now()
ExactMilliseconds since the program's time origin (process start), as a double. The origin is captured once at process start, matching the spec's origin-relative reading; the clock is monotonic and nanosecond-grained, like libuv's uv_hrtime. Unlike Date.now(), it is not tied to wall-clock time.
Returnsnumber — Milliseconds since process start, as a double.
const t1: number = performance.now()
for (let i = 0; i < 200000; i++) { arr.push(i) }
const t2: number = performance.now()
console.log(t2 >= t1) // trueperformance.mark / measure / getEntries* / clearMarks / clearMeasures / timerify / timeOrigin
ExactUser timing as Node keeps it. mark(name) records a PerformanceMark (with an optional structured-cloned detail and startTime); measure(name, start?, end?) or measure(name, options) records a PerformanceMeasure spanning two marks or timestamps, through now when the end is omitted. getEntries/getEntriesByName/getEntriesByType read the timeline in start order; a mark that was never set throws a SyntaxError DOMException.
ReturnsPerformanceMark | PerformanceMeasure — The recorded entry.
performance.mark("loop-start")
for (let i = 0; i < 200000; i++) { arr2.push(i) }
performance.mark("loop-end")
const loopMs: number = performance.measure("loop", "loop-start", "loop-end").durationDate
Works, with caveatsA thin wrapper over milliseconds-since-epoch. Constructs from no argument (now), a millisecond number, an ISO string, or year/month/day/... fields (month 0-indexed, omitted trailing fields defaulting like real JS). Provides the local getFullYear/Month/Date/Day/Hours/Minutes/Seconds/Milliseconds and their getUTC* forms, getTimezoneOffset, getTime/valueOf, toISOString and toString, in the host's time zone as Node's are. The set* and setUTC* setters write the time value back. An unparseable string, NaN or a time past ±8.64e15 ms makes an Invalid Date, whose getters are all NaN.
ReturnsDate — A Date value (a plain number under the hood).
const epoch: Date = new Date(0)
console.log(epoch.getFullYear()) // 1970
const later: Date = new Date(1700000000000)
console.log(later.toISOString())- toString's zone name comes from a built-in table of the common zones' abbreviations; a zone outside it prints the C library's abbreviation (GMT-0300 (-03) where Node says (Brasilia Standard Time))
Date.now()
ExactMilliseconds since the epoch, via clock_gettime(CLOCK_REALTIME, ...). Wall-clock time, unlike performance.now().
Returnsnumber — Milliseconds since the Unix epoch.
const nowMs: number = Date.now()
const now: Date = new Date()Date.parse(string)
ExactParses the ECMAScript date-time format (a date-only form as UTC, a date-time without an offset as local time, Z or a +HH:MM/-HH:MM offset) and V8's legacy forms: toString and toUTCString output, "Jul 15 2024", "2024/07/15 10:30".
Returnsnumber — Milliseconds since epoch, or NaN if unparseable.
console.log(Date.parse('2023-11-14T22:13:20.000Z')) // 1700000000000
console.log(Date.parse('2023-11-14')) // 1699920000000
console.log(Date.parse('not a date')) // NaNDate setters (setFullYear, setMonth, setDate, setHours, setMinutes, setSeconds, setMilliseconds, setTime)
ExactMutate the Date in place, whatever the receiver (a variable, a field, an element, a call result), and return the new time value, matching real JS.
Returnsnumber — The new timestamp after mutation.
const editable: Date = new Date(0)
const newTimestamp: number = editable.setFullYear(2020)
editable.setMonth(5)
editable.setDate(15)Date arithmetic (date ± durationMs, date - date, date += durationMs)
ExactTypeScript rejects arithmetic on a Date, and so does the default strict lane (a compound date += n too): the millisecond count is getTime(). Under -compat=js, date + x concatenates the date string, date - x reads its millisecond count, and date += n makes the variable that string, matching real JS.
Returnsstring | number — A string for +; a number for -, *, / and %.
const start: Date = new Date(0)
const tomorrow: Date = new Date(start.getTime() + oneDayMs)
const elapsedMs: number = tomorrow.getTime() - start.getTime()
console.log(elapsedMs) // 86400000Date.prototype.toDateString()
ExactA fixed "Www Mon DD YYYY" shape (e.g. "Thu Jan 01 1970") in local time, as real JS gives it.
Returnsstring — The date as a "Www Mon DD YYYY" string.
const launch: Date = new Date(1700000000000)
console.log(launch.toDateString()) // Tue Nov 14 2023Date.prototype.toLocaleDateString()
Works, with caveatsMimics real JS's default (en-US, no explicit locale) "M/D/YYYY" output.
Returnsstring — The date as a "M/D/YYYY" string.
const launch: Date = new Date(1700000000000)
console.log(launch.toLocaleDateString()) // 11/14/2023- One fixed
"M/D/YYYY"format (the default en-US shape) in local time; no locale argument or fullIntl-style locale support
Date.prototype.toTimeString() / toJSON()
ExacttoTimeString is toString's time and zone part, in local time; toJSON is toISOString, and null for an Invalid Date (what JSON.stringify writes for one).
Returnsstring — "13:04:09 GMT+0000 (Coordinated Universal Time)", or the ISO form.
const d = new Date(Date.UTC(2020, 0, 5, 13, 4, 9))
console.log(d.toJSON()) // 2020-01-05T13:04:09.000Z
console.log(new Date(NaN).toJSON()) // nullDate.prototype.toLocaleTimeString() / toLocaleString()
Works, with caveatsThe default en-US shapes in local time: "1:04:09 PM", and the date with it, "1/5/2020, 1:04:09 PM".
Returnsstring — The local time, or date and time, in en-US form.
const d = new Date(Date.UTC(2020, 0, 5, 13, 4, 9))
console.log(d.toLocaleString()) // 1/5/2020, 1:04:09 PM (TZ=UTC)- One fixed en-US shape; no locale argument or full Intl-style locale support
PerformanceObserver
ExactObserves performance entries. observe({ entryTypes }) or observe({ type, buffered }) subscribes; the callback receives a PerformanceObserverEntryList (sorted by start time) on a later turn of the event loop, as in Node. disconnect() and takeRecords() work, and supportedEntryTypes lists the known types.
Parameters- callback(list) => void
- Invoked with the entry list.
PerformanceObserver — The observer handle.
import { PerformanceObserver } from 'perf_hooks'
const obs = new PerformanceObserver((list) => {
for (const e of list.getEntries()) console.log(e.name, e.duration)
})
obs.observe({ entryTypes: ['measure'] })
performance.mark('a'); performance.mark('b')
performance.measure('a-b', 'a', 'b')createHistogram / monitorEventLoopDelay
Works, with caveatsperf_hooks histograms: a RecordableHistogram takes record(value)/recordDelta()/add(other); monitorEventLoopDelay samples how late an interval timer runs while enabled. Both report count, min, max, mean, stddev, exceeds and percentiles, with BigInt forms.
ReturnsRecordableHistogram | IntervalHistogram — The histogram.
import { createHistogram } from 'perf_hooks'
const h = createHistogram()
h.record(5); h.record(10); h.record(15)
console.log(h.count, h.min, h.max, h.percentile(50)) // 3 5 15 10- A histogram keeps exact samples, not Node's HDR histogram (3 significant figures): a percentile of large values can differ in its last digits