Skip to content
native-dates

API / Classes

Ranges

Spans between two dates, moments, or times of day, with containment, overlap, and stepping.

import { DateRange, DateTimeRange, TimeRange } from 'native-dates'core 12.1 kB min+br7 min read

Range classes

Create ranges from existing points with to() and range(), or parse endpoints and interval strings with standalone factories on dateRange(). Every range instance is immutable.

Inclusive dates vs half-open clocks

Calendar date ranges include their final day, because September 1 through September 7 means all seven days. Moment and clock ranges exclude their end so back-to-back slots meet without overlapping.

DateRange

new DateRange(start, end, options?)
new DateRange(interval, options?)

Spans two calendar dates and includes both endpoints. Passing an end date earlier than the start date throws a RangeError.

ranges.js
import { date, dateRange } from 'native-dates';

const trip = date('2026-09-01').to('2026-09-07');
const week = dateRange('2026-09-01', '7 days');

trip.duration.days; // 7
week.toString(); // '2026-09-01/2026-09-07'

DateTimeRange

new DateTimeRange(start, end, options?)
new DateTimeRange(interval, options?)

Spans two moments, including start and excluding end. When the end input carries no explicit time zone, it is read in the start moment’s zone, and backwards endpoints throw a RangeError.

import { datetime, datetimeRange } from 'native-dates';

const standup = datetime('2026-09-01T09:00', 'America/New_York').to('30m');
const block = datetimeRange('2026-09-01T09:00', '2026-09-01T10:30', 'America/New_York');

standup.duration.minutes; // 30
block.end.hour; // 10

TimeRange

new TimeRange(start, end, options?)
new TimeRange(interval, options?)

Spans two times of day, including start and excluding end. When the end time is earlier on the clock than the start time, the range wraps across midnight to model overnight hours.

import { time, timeRange } from 'native-dates';

const dayShift = time('9:00am').to('5:00pm');
const nightShift = timeRange('22:00', '06:00');

dayShift.duration.hours; // 8
nightShift.duration.hours; // 8

Properties

Every range exposes its formatted label, typed endpoints, kind tag, and measured length.

Property Type Description
text string Locale-formatted range string, such as 'Sep 1 – 7, 2026'.
start, end CalendarDate | DateTime | Time Start and end points matching the range class.
kind 'date' | 'datetime' | 'time' Tag naming which kind of points the range holds.
duration Duration Full length anchored at start, counting the last day on date ranges and crossing midnight on overnight clock ranges.

Building from points

to()

d.to(end): DateRange
d.to(count, unit): DateRange
dt.to(end): DateTimeRange
dt.to(count, unit): DateTimeRange
t.to(end): TimeRange
t.to(count, unit): TimeRange

Builds a range from this point to an end point or across a duration. On a calendar date, passing a length of 7 days lands six days after start because both endpoints are included.

endPoint | DurationInput | numberrequired

Target endpoint of the same kind, duration input, or numeric count paired with unit.

unitUnit

Unit name when the first argument is a numeric count.

DateRange | DateTimeRange | TimeRange

A range matching the receiver's kind.

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

date('2026-09-01').to(7, 'days').toString(); // '2026-09-01/2026-09-07'
datetime('2026-09-01T09:00Z', 'UTC').to(90, 'minutes').toString(); // '2026-09-01T09:00:00.000Z/2026-09-01T10:30:00.000Z'
time('9:00am').to('5:00pm').toString(); // '09:00:00/17:00:00'

range()

d.range(unit, firstDay?): DateRange
dt.range(unit, firstDay?): DateTimeRange

Returns the full calendar or clock unit enclosing a date or moment. Date ranges span the first through last day of the unit, while moment ranges span from the unit’s start until the start of the next unit.

unitUnitrequired

Enclosing unit such as 'week', 'month', or 'day'.

firstDayWeekday

First day of the week when unit is 'week', overriding configure().

DateRange | DateTimeRange

Enclosing range for unit.

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

date('2026-11-18').range('week').toString(); // '2026-11-16/2026-11-22'
date('2026-02-10').range('month').toString(); // '2026-02-01/2026-02-28'
datetime('2026-11-16T14:20Z', 'UTC').range('hour').toString(); // '2026-11-16T14:00:00.000Z/2026-11-16T15:00:00.000Z'

Containment and overlap

contains()

range.contains(value): boolean

Checks whether a point or another range of the same kind lies inside this range. Date ranges include end, moment and clock ranges exclude it, and overnight clock ranges match times on either side of midnight.

valuePoint | Rangerequired

Point input or range of the same kind.

boolean

true when value falls inside this range.

const stay = dateRange('2026-09-01', '2026-09-07');
stay.contains('2026-09-07'); // true

const night = timeRange('22:00', '06:00');
night.contains('23:30'); // true
night.contains('02:15'); // true
night.contains('06:00'); // false

overlaps()

range.overlaps(other): boolean

Returns true when two ranges of the same kind share at least one day or instant. Back-to-back moment or clock slots where the first ends at the second’s start do not overlap.

otherRange | stringrequired

Range instance or interval string of the same kind.

boolean

true when both ranges share time.

const firstSlot = timeRange('09:00', '10:00');
const nextSlot = timeRange('10:00', '11:00');

firstSlot.overlaps(nextSlot); // false
dateRange('2026-09-01', '2026-09-05').overlaps('2026-09-05/2026-09-10'); // true

intersection()

range.intersection(other): Range | null

Returns a new range covering only the span shared by both ranges, or null when they are disjoint. Two overnight clock ranges that cross in two separate pieces throw a RangeError.

otherRange | stringrequired

Range instance or interval string of the same kind.

DateRange | DateTimeRange | TimeRange | null

Overlapping range of the same kind, or null when disjoint.

const a = dateRange('2026-09-01', '2026-09-10');
const b = dateRange('2026-09-05', '2026-09-15');

a.intersection(b)?.toString(); // '2026-09-05/2026-09-10'
a.intersection('2026-09-20/2026-09-25'); // null

equals()

range.equals(other): boolean

Returns true when both ranges have equal start and end points. Arrays of ranges also sort chronologically with compare().

dateRange('2026-09-01', '2026-09-07').equals('2026-09-01/2026-09-07'); // true

isEmpty()

range.isEmpty(): boolean

Returns true when a moment or clock range has identical start and end points. Always returns false on a DateRange because a single calendar date spans one full day.

timeRange('09:00', '09:00').isEmpty(); // true
dateRange('2026-09-01', '2026-09-01').isEmpty(); // false

Stepping, splitting, and zones

points()

range.points(step): Point[]
range.points(count, unit): Point[]

Walks forward from start by a positive unit or duration and returns every point inside the range. Steps count out from the starting point rather than chaining additions, so stepping monthly from January 31 lands on each month’s final day.

stepUnit | DurationInput | numberrequired

Unit name such as 'day', duration input, or numeric count paired with unit.

unitUnit

Unit name when step is a number.

Array<CalendarDate | DateTime | Time>

Ordered array of points inside the range.

dateRange('2026-01-31', '2026-04-30').points('month').map(String);
// ['2026-01-31', '2026-02-28', '2026-03-31', '2026-04-30']

timeRange('22:00', '02:00').points(1, 'hour').map(String);
// ['22:00:00', '23:00:00', '00:00:00', '01:00:00']

split()

range.split(step): Range[]
range.split(count, unit): Range[]

Divides the range into contiguous sub-ranges of the given step size, clamping the final chunk to the range’s end. Accepts the same step arguments as points().

dateRange('2026-09-01', '2026-09-10').split(4, 'days').map(String);
// ['2026-09-01/2026-09-04', '2026-09-05/2026-09-08', '2026-09-09/2026-09-10']

in()

dateRange.in(zone?): DateTimeRange
dtRange.in(zone): DateTimeRange

Converts a DateRange into a half-open DateTimeRange from midnight on the start day until midnight after the final day, matching timestamp query bounds. On a moment range, shifts both endpoints into the target time zone.

Calling in() on a clock range throws a RangeError because times of day have no calendar date.

zoneZone

Target IANA zone, fixed offset, or 'UTC'. Defaults to the configured zone on DateRange.

DateTimeRange

Half-open moment range in zone.

dateRange('2026-09-01', '2026-09-03').in('UTC').toString();
// '2026-09-01T00:00:00.000Z/2026-09-04T00:00:00.000Z'

Formatting and conversion

format()

range.format(spec?, locale?): string

Formats the range with localized Intl range formatting for presets and options objects, collapsing shared dates or months automatically. Token patterns like 'YYYY-MM-DD' format each endpoint with the pattern and join them with ' – '.

See Formatting for preset and token details.

specFormatSpec

Preset name, Intl.DateTimeFormatOptions object, or token pattern.

localeLocale

BCP 47 locale tag overriding the configured default for this call.

string

Formatted range string.

const trip = dateRange('2026-09-01', '2026-09-07');

trip.format('medium', 'en-US'); // 'Sep 1 – 7, 2026'
trip.format('YYYY-MM-DD'); // '2026-09-01 – 2026-09-07'
timeRange('22:00', '06:00').format('HH:mm'); // '22:00 – 06:00'

as()

range.as('duration'): Duration

Returns the range’s duration when 'duration' is requested in method chains, throwing a RangeError for other kinds.

dateRange('2026-09-01', '2026-09-07').as('duration').days; // 7

toString()

range.toString(): string
range.toJSON(): string

Returns the ISO 8601 interval string 'start/end', which parses back directly in the range factories. toJSON() returns the same string for JSON serialization.

dateRange('2026-09-01', '2026-09-07').toString(); // '2026-09-01/2026-09-07'
timeRange('9am', '5pm').toJSON(); // '09:00:00/17:00:00'

valueOf()

range.valueOf(): never

Throws a RangeError so numeric operators never coerce a range to a number.

Narrow unknown values at runtime with kindOf() or the exported range guard functions:

import { dateRange, isDateRange, isDateTimeRange, isTimeRange } from 'native-dates';

const stay = dateRange('2026-09-01', '2026-09-07');
isDateRange(stay); // true
isDateTimeRange(stay); // false
isTimeRange(stay); // false
Edit this pageUpdated Nov 12, 2026