Guides / Working with time
Parsing
Read ISO strings, clock times, duration phrases, and user input into the right type without silent guesswork.
Core parses standard, unambiguous inputs directly into the type you ask for:
datetime()for moments in time, epoch milliseconds, and timestampsdate()for calendar days with no clock or time zonetime()for 24-hour and 12-hour times of dayduration()for human unit phrases and ISO 8601 durations
ISO dates and timestamps
Pass an ISO date string, three year, month, and day numbers, or a fields object to date().
Months run from 1 through 12. Impossible calendar dates like February 30 throw an error instead of rolling forward into March.
import { date } from 'native-dates';
date('2026-11-16');
date(2026, 11, 16);
date({ year: 2026, month: 11, day: 16 });Pass ISO 8601 strings or fields objects to datetime(). A trailing Z or numeric offset identifies the exact moment, while a string without an offset reads as local time in the target zone.
import { datetime } from 'native-dates';
datetime('2026-11-16T17:30:00Z', 'America/Los_Angeles'); // 9:30 AM PST
datetime('2026-11-16T09:30', 'America/Los_Angeles'); // 9:30 AM PST
datetime('2026-11-16T09:30[Europe/Berlin]'); // 9:30 AM CET
datetime({ year: 2026, month: 11, day: 16, hour: 9, minute: 30 }, 'Europe/Berlin');Passing an offset timestamp directly to date() throws because its calendar day depends on where you view it. Read the moment in a zone first, then read .date:
datetime('2026-11-17T01:30:00Z', 'America/Los_Angeles').date; // 2026-11-16
datetime('2026-11-17T01:30:00Z', 'Asia/Tokyo').date; // 2026-11-17Clock times and durations
Pass 24-hour ISO times, 12-hour clock strings, numeric arguments, or a fields object to time().
import { time } from 'native-dates';
time('09:30');
time('9:30am');
time('5:15 PM');
time(17, 15, 30);
time({ hour: 9, minute: 30 });Pass plain-English unit phrases, ISO 8601 duration strings, a count and unit, or a fields object to duration().
import { duration } from 'native-dates';
duration('1h 30m');
duration('2 weeks and 3 days');
duration('PT90M');
duration(90, 'minutes');
duration({ hours: 1, minutes: 30 });Epoch timestamps, Date, and Temporal
datetime() also reads epoch milliseconds, native Date instances, and Temporal objects.
Passing a bare number to a date factory throws as ambiguous. Convert epoch milliseconds to a moment in a zone first, then read its calendar day.
import { date, datetime } from 'native-dates';
const fromEpoch = datetime(1794850200000, 'UTC');
const fromJSDate = datetime(new Date('2026-11-16T17:30:00Z'));
const localDay = date(new Date('2026-11-16T17:30:00Z'), 'America/Los_Angeles');Why ambiguous strings throw
A string like '03/05/2026' means March 5 in the United States and May 3 across Europe and Latin America. Core refuses locale-dependent strings rather than guessing the wrong month in production.
User input with the loose plugin
When parsing free-form text from user inputs, CSV exports, or RFC 2822 headers, import @native-dates/plugins/loose and pass { loose: true }.
import '@native-dates/plugins/loose';
import { date, datetime } from 'native-dates';
date('Nov 16, 2026', { loose: true }); // 2026-11-16
datetime('Mon, 16 Nov 2026 17:30:00 GMT', { loose: true });Numeric slash and dot dates default to month-first order. Pass dayFirst: true per call, or set it once at startup with configure(), when reading day-first dates.
date('03/05/2026', { loose: true }); // 2026-03-05
date('03/05/2026', { loose: true, dayFirst: true }); // 2026-05-03With { loose: true }, unreadable inputs return null instead of throwing across every factory, keeping form validation to a simple check. Invalid option values like an unknown time zone name still throw immediately.
import { duration } from 'native-dates';
date('not a date', { loose: true }); // null
duration('soon', { loose: true }); // null