On This Page
Dates - Reading Values
The factories read ISO 8601 and refuse the rest, with the way out in the error. { loose: true } reads whatever the engine’s Date reads and gives null for what cannot be read.
Strict by Default
Every factory takes the value first, then a zone or an options object.
datetime(input, zone);datetime(input, { zone, loose, dayFirst });A missing value refuses too. now() and today() are the doors for the present, so an absent field never silently becomes now.
Datetimes
datetime('2026-09-06T14:30Z'); // an instantdatetime('2026-09-06T14:30:00+09:00'); // an instant, the offset never becomes the zonedatetime('2026-09-06T14:30', 'Asia/Tokyo'); // a wall clock in the zonedatetime('2026-09-06T14:30:00+09:00[Asia/Tokyo]'); // a bracketed zone is the zonedatetime('2026-09-06', 'UTC'); // midnightDates
date('2026-09-06');date(2026, 9, 6);date('2026-09-06T23:30'); // a wall-clock string keeps its dayA string carrying Z or an offset is an instant whose day depends on the zone, so date('2026-09-06T23:30Z') refuses. datetime(text, zone).date chooses the zone, and so does { loose: true, zone }.
A bare number refuses as well, since date(2026) is a year to one reader and epoch milliseconds to another. Epoch milliseconds are a datetime, datetime(n).date.
Times
time('09:00');time('9am');time('5:30 pm');time('17:30:15.250');time(9, 30);Durations
duration('1h 30m');duration('2 weeks and 3 days');duration('PT1H30M');duration(90, 'minutes');duration(1500); // a bare number is millisecondsEvery spelling toDuration in @semantic-ui/utils reads is read here, plus compounds, calendar units and fractions. '1.5 days' is a day and twelve hours. A fraction of a month refuses, and so does a phrase with mixed signs like '1h -30m', since a length has one sign.
Ranges
dateRange('2026-09-01', '2026-09-07');dateRange('2026-09-01/2026-09-07'); // ISO interval notationdateRange('2026-09-01 - 2026-09-07'); // a text field's own separators readtimeRange('9am to 5pm');dateRange('2026-09-01', '1 week'); // an end written as a length is oneAn end reads through the range’s own kind first, so '5pm' is a time, and as a length when written as one, '2h', { hours: 2 } or a duration.
The Loose Door
{ loose: true } is the options form of the last argument on all seven factories.
date('September 6, 2026', { loose: true }).toString(); // '2026-09-06'date('9/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'What Returns Null
A point that is not one, a length that is not one, and a range with such an end give null rather than a throw, so a form field reads in one line.
date('someday', { loose: true }); // nulldatetime(undefined, { loose: true }); // nullduration('5 foos', { loose: true }); // nulldateRange('garbage', '2026-09-07', { loose: true }); // nullA loose wall clock stands in the zone it is read in, and a loose string that names its own instant keeps it.
configure({ zone: 'America/Los_Angeles' });datetime('September 6, 2026 5:30 PM', { loose: true }).format('HH:mm z'); // '17:30 PDT'What Still Throws
What reads but is wrong is a mistake in the code rather than in the data’s form, so it still throws under loose: a backwards range, an unknown zone, a unit that is not one.
datetime('banana', { loose: true, zone: 'Mars/Olympus' }); // throws unknownZoneDay First
A numeric date reads in the engine’s order, so 07.09.2026 is July 9th. dayFirst says the app’s users write the day first, the one knob most of the world needs.
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'datetime('07.09.2026 5:30 PM', { loose: true }).format('YYYY-MM-DD HH:mm'); // '2026-09-07 17:30'Other Inputs
A Date object is read everywhere without asking. It is an instant, so its day and clock depend on the zone it is read in.
datetime(new Date(0), 'UTC').toString(); // '1970-01-01T00:00:00.000Z'date(new Date('2026-09-06T23:30:00Z'), 'Asia/Tokyo').toString(); // '2026-09-07'time(new Date('2026-09-06T14:30:00Z'), 'Asia/Tokyo').toString(); // '23:30:00'A fields object reads with singular keys for a point and plural keys for a length, as Temporal spells them.
datetime({ year: 2026, month: 9, day: 6, hour: 9 }, 'UTC');date({ year: 2026, month: 2, day: 28 });duration({ hours: 1, minutes: 30 });A value of another kind reads where it makes sense: a datetime gives its date or its time in its zone, a date reads as its midnight in a zone, and a Temporal value of the matching type reads as itself.
date(datetime('2026-09-06T23:30Z').in('Asia/Tokyo')).toString(); // '2026-09-07'time(datetime('2026-09-06T14:30Z', 'UTC')).toString(); // '14:30:00'datetime(Temporal.Instant.from('2026-09-06T09:00:00Z'), 'UTC').hour; // 9Every method that takes another point takes the same inputs as its factory, so dt.isBefore('2027-01-01') and range.contains('2026-09-07') read the string through the kind’s own rules.