Skip to content
native-dates

Guides / Going further

Coming from Day.js

Replace dayjs() wrappers and plugin chains with dedicated date types, 1-indexed months, and built-in time zones.

Day.js wraps a JavaScript date in a single dayjs() object and adds time zones, UTC, and durations through plugins. Moving here keeps the lightweight, immutable style while giving calendar days, clock times, moments, and durations their own types.

Pick date() or datetime()

In Day.js, both a birthday and an API timestamp go through dayjs().

Here, use date() or today() for calendar days that stay the same everywhere.

Use datetime() or now() when something happens at a real moment in time.

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

const current = now(); // replaces dayjs() for a timestamp
const due = today().plus(2, 'weeks'); // replaces dayjs().add(2, 'week') for a day
const created = datetime('2026-11-16T17:30:00Z');
const birthday = date('2026-05-10');

Both add() and subtract() work as aliases if your codebase already uses those names. Passing an empty value to a factory throws instead of silently returning the current time, catching missing API fields early.

Months start at 1

Day.js inherits zero-indexed months where January is 0 and .date() reads the day of the month. Here, calendar fields are plain properties and months run from 1 through 12.

import { date } from 'native-dates';

const d = date('2026-11-16');

d.year; // 2026
d.month; // 11, November
d.day; // 16
d.weekday; // 1, Monday

Check month and weekday numbers

Day.js numbers months from 0 to 11 and starts weekdays on Sunday at 0. Here, month runs from 1 through 12, and weekday runs from 1 on Monday through 7 on Sunday.

Time zones and durations built in

Day.js requires separate plugins before you can convert across cities or build durations. Core includes IANA time zones, UTC serialization, and Duration math with zero setup.

import { datetime, duration, hours } from 'native-dates';

const standup = datetime('2026-11-16T09:30', 'America/Los_Angeles');
const berlin = standup.in('Europe/Berlin'); // replaces .tz('Europe/Berlin')

const span = duration('1h 30m').plus(hours(0.5));
span.total('minutes'); // 120

Presets vs token strings

Token strings in Day.js embed English word order unless you bundle extra locale files. Core formats through Intl presets such as short, medium, and long, adapting automatically to any locale.

When you want custom token patterns for fixed layouts or filenames, import @native-dates/plugins/tokens:

import '@native-dates/plugins/tokens';
import { datetime } from 'native-dates';

const dt = datetime('2026-11-16T17:30:00Z', 'America/New_York');

dt.format('medium', 'en-US'); // 'Nov 16, 2026, 12:30 PM'
dt.format('YYYY-MM-DD HH:mm'); // '2026-11-16 12:30'

Relative time and ranges

Specialized features ship as opt-in subpaths under @native-dates/plugins with no global registration call required. Import only the capabilities your app uses.

import '@native-dates/plugins/relative';
import { dateRange } from '@native-dates/plugins/ranges';
import { date, today } from 'native-dates';

today().minus(3, 'days').formatRelative(); // '3 days ago'
dateRange('2026-11-01', '2026-11-30').contains(date('2026-11-16')); // true

Instead of passing bracket inclusivity strings, date ranges include both calendar endpoints and datetime ranges exclude their end moment automatically.

Side-by-side reference

Day.js Native Dates Notes
dayjs() now() or today() Choose an exact moment or a calendar day
d.month(), d.date() d.month, d.day Plain properties with months from 1 to 12
d.add(2, 'day') d.plus(2, 'days') add() and subtract() aliases also work
dayjs.tz(x, zone) datetime(x, zone) Built into core with no timezone plugin
d.tz(zone) dt.in(zone) Views the same moment in another IANA zone
dayjs.utc(x) datetime(x, 'UTC') Built into core with no utc plugin
b.diff(a, 'day', true) a.until(b, 'days') Fractional total in the requested unit
dayjs.duration(90, 'm') minutes(90) or duration('90m') Built into core with no duration plugin
d.format('LL') d.format('long') Uses browser Intl with zero locale bundles
d.format('YYYY-MM-DD') d.toString() or tokens ISO strings are built in, or load tokens
d.fromNow() d.formatRelative() Provided by @native-dates/plugins/relative
d.isBetween(a, b) dateRange(a, b).contains(d) Provided by @native-dates/plugins/ranges
customParseFormat { loose: true } Provided by @native-dates/plugins/loose
Edit this pageUpdated Nov 12, 2026