Skip to content
native-dates

Guides / Going further

Working with Temporal

How Native Dates maps onto JavaScript's Temporal API, accepts raw Temporal objects, and runs on older engines.

Native Dates is a thin, ergonomic layer over JavaScript’s built-in Temporal and Intl APIs.

Temporal provides exact calendar and time-zone primitives with explicit option bags. Native Dates wraps everyday callsites in concise methods while interoperating freely with raw Temporal instances.

How types map to Temporal

Each class wraps one underlying Temporal type and hands it back whenever you need low-level control:

Type Wraps What Native Dates adds
DateTime Temporal.ZonedDateTime Reads ISO instants, offsets, Date, and epoch numbers into one zoned type and serializes to UTC
CalendarDate Temporal.PlainDate Pairs with at(time, zone) and formats locale presets directly through Intl
Time Temporal.PlainTime Reads 12-hour strings like '9:30am' alongside 24-hour ISO clock times
Duration Temporal.Duration Parses '1h 30m' phrases, spills fractional units, and remembers anchors from until()

Passing Temporal objects in

Every factory, arithmetic method, and comparison accepts raw Temporal values directly without manual conversion steps.

import { date, datetime, time } from 'native-dates';

const instant = Temporal.Instant.from('2026-11-16T17:30:00Z');
const standup = datetime(instant, 'America/Los_Angeles');

const plainDate = Temporal.PlainDate.from('2026-11-16');
date(plainDate).plus(Temporal.Duration.from({ weeks: 2 }));

const plainTime = Temporal.PlainTime.from('09:30');
time(plainTime).format('short', 'en-US'); // '9:30 AM'

Passing a Temporal.ZonedDateTime to datetime() preserves its time zone unless you pass a new one. Passing an instant or plain date-time places that value into the zone you specify or your configured default.

Comparisons and span measurements accept Temporal inputs directly too:

const berlin = Temporal.ZonedDateTime.from('2026-11-16T18:30:00+01:00[Europe/Berlin]');
standup.equals(berlin); // true

Unwrapping with toTemporal()

Call toTemporal() on any value to access its underlying Temporal instance.

Use it when calling third-party libraries that expect Temporal objects, working with non-ISO calendar systems, or converting to PlainYearMonth and PlainMonthDay.

import { date } from 'native-dates';

const d = date('2026-11-16');
const plain = d.toTemporal(); // Temporal.PlainDate

const japanese = plain.withCalendar('japanese');
japanese.era; // 'reiwa'
japanese.eraYear; // 8

plain.toPlainYearMonth().toString(); // '2026-11'

Zero-copy unwrapping

Each instance holds a real Temporal object internally, so toTemporal() returns that object directly without reparsing or allocating a copy.

Polyfilling older runtimes

Modern browsers and current Node releases ship Temporal natively, so core includes zero polyfill code in its bundle.

If your application supports older browsers or Node versions without native support, install @native-dates/polyfill alongside temporal-polyfill:

npm install @native-dates/polyfill temporal-polyfill

Import @native-dates/polyfill once at your application entry point before importing from Native Dates:

import '@native-dates/polyfill';
import { today } from 'native-dates';

today().plus(1, 'week');

The default entry checks globalThis.Temporal first and dynamically imports the polyfill only when needed, so modern browsers skip downloading it. In environments without top-level await, import '@native-dates/polyfill/sync' instead.

Edit this pageUpdated Nov 12, 2026