Skip to content
native-dates

Plugins / Reference

loose plugin

Opt-in fallback parsing and null returns for untrusted text from forms, CSVs, and legacy feeds.

import '@native-dates/plugins/loose'0.2 kB min+br

Opt-in loose parsing

Every factory parses strict ISO 8601 strings by default and throws on malformed input. Importing this plugin enables { loose: true } for untrusted user text, CSV columns, and legacy headers.

loose.js
import '@native-dates/plugins/loose';
import { date, datetime, duration, time } from 'native-dates';

date('September 6, 2026', { loose: true })?.toString(); // '2026-09-06'
datetime('Sat, 06 Sep 2026 14:30:00 GMT', { loose: true })?.toString();
// '2026-09-06T14:30:00.000Z'
time('September 6, 2026 5:30 PM', { loose: true })?.toString(); // '17:30:00'
duration('2h', { loose: true })?.toString(); // 'PT2H'

Strict parsing stays the default wherever you omit { loose: true }. Importing the plugin never alters existing calls across your codebase.

Returning null on bad data

With loose mode enabled, unreadable strings, empty fields, missing values, and impossible calendar dates like February 30 return null instead of throwing. Form handlers and import scripts can check the result directly without wrapping every field in a try block.

const submitted = date('TBD', { loose: true }); // null
const rolled = date('2026-02-30', { loose: true }); // null
const missing = datetime(undefined, { loose: true }); // null

Range factories from ranges accept the same option and return null if either endpoint cannot be read:

import { dateRange } from '@native-dates/plugins/ranges';

dateRange('Sep 1 2026', 'Sep 7 2026', { loose: true })?.toString(); // '2026-09-01/2026-09-07'
dateRange('TBD', '2026-09-07', { loose: true }); // null

Bad data returns null, bad options still throw

Loose mode only forgives unreadable input data. Passing an unknown time zone like 'Mars/Olympus' is a mistake in application code rather than user input, so it still throws immediately.

Time zones on loose strings

Strings carrying a UTC marker or numeric offset identify a specific moment and convert it into your target or configured zone. Strings without an offset keep the exact date and time written in the text and place them directly in your target zone.

datetime('Sat, 06 Sep 2026 14:30:00 GMT', {
  loose: true,
  zone: 'America/New_York',
})?.hour; // 10

datetime('September 6, 2026 5:30 PM', {
  loose: true,
  zone: 'America/Los_Angeles',
})?.hour; // 17

Day-first numeric dates

Numeric dates written with slashes, dots, or hyphens default to month-first order. Pass dayFirst: true per call or set it app-wide with configure() for regions that write the day before the month.

import { configure } from 'native-dates';

date('07.09.2026', { loose: true })?.toString(); // '2026-07-09'
date('07.09.2026', { loose: true, dayFirst: true })?.toString(); // '2026-09-07'

configure({ dayFirst: true });
date('7/9/26', { loose: true })?.toString(); // '2026-09-07'
date('07.09.2026', { loose: true, dayFirst: false })?.toString(); // '2026-07-09'
configure({ dayFirst: false });

Factory options

datetime()

datetime(input, { loose: true, zone?, dayFirst? }): DateTime | null
date(input, { loose: true, zone?, dayFirst? }): CalendarDate | null
time(input, { loose: true, zone?, dayFirst? }): Time | null
duration(input, { loose: true }): Duration | null

Extends core factories and range factories with fallback parsing and null returns on unreadable input. Calling class constructors like new DateTime() with { loose: true } enables fallback parsing while still throwing if the input cannot be read.

loosebooleandefault false

Fall back to engine Date parsing and return null when input cannot be read.

dayFirstbooleandefault false

Read numeric dates like '07.09.2026' with the day before the month.

zoneZone

Time zone used to interpret local date-time strings or view instants.

DateTime | CalendarDate | Time | Duration | null

Parsed instance, or null when input cannot be read.

const parsed = date('2026-09', { loose: true });
parsed?.toString(); // '2026-09-01'

configure()

configure({ dayFirst }): Settings

Sets the default numeric date order for all loose calls that do not specify dayFirst explicitly.

dayFirstbooleandefault false

When true, loose numeric dates default to day-first order across the app.

Edit this pageUpdated Nov 12, 2026