Components · Forms

Date & time picker

Clinical time is not calendar time. It carries a timezone, it cannot run forwards, it has two ambiguous hours a year, and getting it wrong changes what a trend means.

Stable · v1.0 shadcn/ui ISO 8601 WCAG 2.2 AA

Overview

Almost every clinical decision this system supports is a decision about change over time: ST elevation compared with a prior, troponin across a 0/1 h interval, how long a patient has waited. All of it rests on timestamps being unambiguous, ordered and correctly zoned — and a picker is where a human introduces the error.

Unambiguous

ISO 8601, 24-hour, with the timezone visible. A date that means two things depending on where you trained is not a date.

Bounded

Observations cannot be in the future. Constraints are stated before entry, not discovered after it.

Typeable

The calendar is an aid. A clinician who knows the date types it — six taps to reach last Tuesday is a failure of the control, not of the user.

Anatomy

Date field with calendar aid
YYYY-MM-DD · local time, Europe/Vienna
August 2026 CEST
Mo
Tu
We
Th
Fr
Sa
Su
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
selected 2026-08-11 · today 2026-08-13 · future dates disabled
ElementRule
Text field The primary input. Accepts a typed ISO date and is never read-only in favour of the calendar.
Format hint YYYY-MM-DD, always visible, plus the timezone the value is interpreted in.
Calendar An aid. Marks today distinctly from the selection, and disables what is out of range rather than silently rejecting it.
Footer Restates the selection in full, and names the active constraint.

Format

ISO 8601, always

04/12/57 is 4 December to a European clinician and 12 April to an American one, and both readings are confident. Dates are entered, displayed, stored and printed as YYYY-MM-DD throughout — no locale-aware formatting, no input masks that reorder fields, no two-digit years. The same rule as Patient header.

Timezone is part of the value

A clinical timestamp without a zone is not a timestamp. Three rules:

The two ambiguous hours

At the end of daylight saving, one local hour occurs twice. A 0/1 h troponin interval spanning it can appear to run backwards, or to be two hours long. The picker resolves this by storing UTC and, where a local time is ambiguous, asking which occurrence is meant rather than guessing. At the spring transition, times inside the skipped hour are rejected with an explanation — they did not exist.

Constraints

Field kindConstraintBehaviour
Observation — acquisition, sample drawn Not in the future Future dates disabled in the calendar; typed future dates rejected with the reason.
Date of birthNot in the future; plausible age range Outside the range confirms rather than rejects — see Text field.
Scheduled — repeat sampling, follow-upUsually future Past dates permitted but confirmed, since back-dating is sometimes correct.
Range — trend windowStart ≤ end Selecting an end before the start reorders them and says so; it never silently swaps.

Constraints are stated before entry, not after. A hint reading "not in the future" costs nothing; discovering it after typing costs a re-entry at the worst moment.

Relative and absolute time

"4 min ago" is easier to read and harder to verify. The rule follows the consequence:

Do
YYYY-MM-DD HH:MM:SS · Europe/Vienna · cannot be in the future

Unambiguous format, named zone, constraint stated before entry.

Don't
Pick a date

Locale-ambiguous order, two-digit year, am/pm, no timezone, no constraint. Four independent ways to record the wrong moment.

Do's and don'ts

Do
YYYY-MM-DD HH:MM:SS · Europe/Vienna · cannot be in the future

Unambiguous format, named zone, constraint stated before entry.

Don't
Pick a date

Locale-ambiguous order, two-digit year, am/pm, no zone, no constraint. Four ways to record the wrong moment.

Accessibility

Outcomes of use

What this contributes to, in the terms of Usability & context of use. These are attributes believed to contribute to an outcome; the outcome itself is settled by observing real use in a specified context, not by this page.

Clinical safety notes

Risk controls carried by this component

Trace these in your risk file (ISO 14971) and usability engineering file (IEC 62366-1).

Implementation

$ npx shadcn@latest add https://md.notjustany.tech/r/date-picker.json
<DateTimeField
  label="ECG acquired"
  kind="observation"        // disallows future values
  precision="second"
  zone="Europe/Vienna"       // site of care, not the reader's browser
  value={value}                // always UTC on the wire
  onChange={setValue}
/>

// Timezone is not optional, because a clinical timestamp without one
// is not a timestamp.
if (!zone) {
  throw new Error(
    "[DateTimeField] `zone` is required. Pass the site of care's zone — " +
    "never infer it from the reader's browser."
  )
}
PropTypeDefaultNotes
kindobservation | birth | scheduled | range Required. Sets the constraint set.
zoneIANA zone Required. Never inferred.
precisionday | minute | second minutesecond for acquisitions and audit events.
valueISO 8601 UTC Local time is a rendering, never the stored value.
NotJustAnyMed.Tech Design System · Date & time picker · v1.0 · draft for review
Reference applications named in this system are fictional; all patient data shown is fabricated.