Skip to content
lingo

Dates & durations

Relative dates against an explicit now, two-way.

Prefer the live demos? Open this section in the interactive docs.

Relative dates parse against an explicit now for reproducible results, and the humanizer output always re-parses within one grain. Import from @pascal-app/lingo/date.

import {
  parseDate,
  parseDateRange,
  humanizeDate,
  humanizeDateRange,
  parseDuration,
  humanizeDuration,
} from "@pascal-app/lingo/date"

parseDate("three days ago", { now }).date       // exact Date, grain "day"
parseDate("17h30", { now })                      // 17:30 today (grain "minute")
parseDate("quarter past 5", { now })             // 05:15
humanizeDate(d, { now })                         // "3 days ago" — re-parseable

// Timezones: exposed by default; opt in to resolve the instant
parseDate("3pm EST", { now }).zone               // { source: "abbrev", offsetMinutes: -300 }
parseDate("3pm EST", { now, applyZone: true })   // the real UTC instant, not host-local

// Time slots, two-way
const slot = parseDateRange("2pm to 4pm", { now }) // { start, end } endpoints
parseDateRange("9-5", { now })                   // workday shift → 09:00–17:00
humanizeDateRange(slot)                          // "2:00 PM to 4:00 PM"

parseDuration("1h30").duration.base              // 5400 (seconds)
humanizeDuration(5400, { style: "natural" })     // "an hour and a half"

Times of day read the way people write them — 17h, 5 o’clock, quarter past 5, 5.30pm, midi/minuit, 0900 hours. A trailing timezone is detected and exposed on .zone while the civil wall-clock is kept; pass applyZone: true to resolve the real UTC instant (offsets, abbreviations, and IANA names resolve DST-correctly via Intl). parseDateRange turns a slot like 2pm to 4pm, between 9am and 5pm, or the 9-5 workday shift into { start, end } endpoints, and humanizeDateRange renders it back.

Reference-dependent input needs an explicit now, so a queued job parses the same date every time. Fully absolute dates never require it. Browse the shorthand it reads under Catalog → Date shorthand and Time slots.