Skip to content

Epoch Utilities

ZEpoch works directly with epoch nanoseconds for callers that want instants without instances — parsers, storage layers, hot paths.

ts
import {ZEpoch} from '@sajajs/zdate'
FunctionDescription
ZEpoch.now()Current epoch nanoseconds (bigint)
ZEpoch.parse(input, options?)Parse any supported format to epoch nanoseconds
ZEpoch.parseSpec(input, options?)Like parse(), returning the full result: epoch, matched spec, and RFC 9557 suffix data
ZEpoch.parseFormat(input, format, options?)Parse localized input against a specifier pattern
ZEpoch.from(fields?, options?)ISO date fields to epoch nanoseconds, with overflow control
ZEpoch.toSeconds(epoch?)Epoch nanoseconds to seconds
ZEpoch.toMilli(epoch?)Epoch nanoseconds to milliseconds
ZEpoch.toMicro(epoch?)Epoch nanoseconds to microseconds

parseSpec

For advanced use cases that need to know what was parsed:

ts
const r = ZEpoch.parseSpec('2024-01-15T12:00:00-05:00[America/New_York][u-ca=hebrew]')

r.epoch                    // bigint
r.spec                     // 'rfc9557'
r.suffix?.zone              // 'America/New_York'
r.suffix?.zoneRequired      // false (critical flag '!')
r.suffix?.calendarRequired  // false (critical flag '!')
r.suffix?.tags?.['u-ca']    // 'hebrew'

parseFormat

Localized input in a known shape, always ISO 8601 calendar; input with no zone or offset is treated as UTC:

ts
const epoch = ZEpoch.parseFormat('14 juillet 2025 14:30', 'DD MMMM YYYY HH:mm', {locale: 'fr-FR'})

from

ISO 8601 date fields to epoch nanoseconds. Omitted fields take their defaults (month and day 1, time fields 0); omitting fields entirely returns the current epoch. Fields resolve in options.zone, defaulting to UTC.

The overflow option controls out-of-range fields:

  • 'reject' (default) — invalid fields throw
  • 'constrain' — each field is clamped to its valid range
  • 'cascade' — larger units absorb the overflow, matching Date.UTC behavior while preserving years 0–99 and resolving zones through zdate
ts
ZEpoch.from({year: 2024, month: 1, day: 15, hour: 12})
ZEpoch.from({year: 2024, month: 14}, {overflow: 'cascade'})            // 2025-02
ZEpoch.from({year: 2024, month: 1, day: 15}, {zone: 'America/New_York'})

Conversions

toSeconds(), toMilli(), and toMicro() floor a nanosecond epoch to the coarser unit. The epoch argument defaults to now.

ts
const d = new Date(ZEpoch.toMilli(zd.epoch))   // platform Date interop
ZEpoch.toSeconds()                             // current Unix seconds

Precision

ZEpoch.now() chooses its source per runtime. In Node, Bun, and Deno it derives the epoch from performance.timeOrigin + performance.now() — nanosecond resolution, and measurably faster than Temporal. In browsers, where performance.now() is precision-reduced for Spectre mitigation, it uses Temporal.Now.instant() when available; without Temporal it falls back to the Performance API at roughly 100 microsecond steps (5 microseconds cross-origin-isolated).