Unambiguous Date

Shows numeric dates as "3 Oct 2026" and asks when 03/10 could mean two dates, so DD/MM and MM/DD aren't mixed up.

Stops03/04 read as March instead of April

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/unambiguous-date.json

The files land in your project. They're yours to edit.

Usage

unambiguous-date-usage.tsx
import { UnambiguousDate, type DateOrder } from "@/components/ui/unambiguous-date"

<UnambiguousDate value={new Date(2026, 9, 18)} now={TODAY} showWeekday />

What it catches

  • Numeric dates with two valid readings (03/10/2026)
  • Impossible dates like 31/02, rejected instead of rolled over
  • Year-first ISO dates, read unambiguously
  • One answer applied to every date in a column

Props

UnambiguousDate props
PropTypeDefault
value* (required)

A Date, an ISO string, or a numeric string like "03/10/2026".

Date | string—
prefer

Which reading to show first when a numeric string is ambiguous.

"DMY" | "MDY""DMY"
now

Reference time for "in 5 days". Defaults to the client clock after mount.

Date—
locale

Locale for month and relative wording. The day-month-year order is fixed.

string"en"
showWeekday

Prefix the weekday: "Sat, 3 Oct 2026".

booleanfalse
onResolve

Called when the user picks a reading for an ambiguous input, or with `null` when they undo it.

(reading: DateReading | null) => void—
order

The reading already chosen for this source, e.g. the order a whole CSV column was confirmed in. When set, ambiguous values use it without asking. Pair with `onResolve` to remember a choice.

"DMY" | "MDY" | null—
invalidMessage

Shown when the value isn't a date.

string"isn’t a date"
readAsText

`{order}` is a reading name.

string"read as {order}"
changeLabel

Label of the change-reading button.

string"change"
alsoText

`{input}` and `{date}` are filled in.

string"“{input}” could also mean {date}."
readingNames

Names of each reading, e.g. `{ DMY: "day/month" }`.

Partial<Record<DateOrder, string>>—

* required. Also accepts the native props of <span> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Readback in a polite live region with a <time dateTime> element
  • Choice buttons are labelled; focus moves to the chosen reading
  • Icons are aria-hidden

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Numeric formats only; month names are not parsed here
  • Two-digit years may be ambiguous

What it stops

03/04 read as March instead of April

Also known as

date format · dd/mm/yyyy · mm/dd/yyyy · date picker · csv import · relative date · dob · locale

Field type

Dependencies

Pairs well with