OPERATOR

DateTimePicker

Usage

Window start

Time zone: America/Los_Angeles

Window start date
Window start time
0130

This wall time occurs twice in America/Los_Angeles.

Committed instant: 2026-11-01 09:30:00 UTC

const [instant, setInstant] = useState<number | null>(
  Date.parse("2026-11-01T09:30:00Z"),
);
const [instantValid, setInstantValid] = useState(true);
 
<DateTimePicker
  id="window-start"
  label="Window start"
  value={instant}
  timeZone="America/Los_Angeles"
  onValueChange={setInstant}
  onDraftValidityChange={setInstantValid}
  required
/>
<Button disabled={!instantValid}>Review</Button>

Instants, drafts, and Apply

The controlled value is integer epoch milliseconds, or null. Supply an IANA timeZone; it is shown alongside the fields. min and max are inclusive epoch-millisecond bounds: the date's calendar offers only the days that hold an instant within them, and an instant outside them is named in UTC, for example "Choose an instant at or after 2026-10-01 12:00:00 UTC." Invalid values, zones, or bounds produce readable errors; a timeZone that is not a string shows as "invalid" with the time zone message.

Date and time edits remain local until Apply. Connect onDraftValidityChange to Review and Save: it reports false for incomplete, invalid, and unapplied edits, including edits that leave the public instant unchanged. It becomes true after the host accepts Apply or supplies another valid value. A declined update retains the pending draft.

The fields edit to minute precision. Applying an edited wall time sets seconds and milliseconds to zero. A supplied instant retains its original seconds and milliseconds while untouched; Apply is disabled until editing begins. Clearing both fields and applying requests null; required fields block an empty draft.

An externally changed instant or time zone replaces the local draft. To discard a draft while retaining both, change the component's React key.

Daylight-saving transitions

A wall time that does not exist is rejected visibly. For example, 2026-03-08 02:30 in America/Los_Angeles falls in the spring-forward gap and cannot be applied.

A repeated wall time requires an explicit earlier or later occurrence. 2026-11-01 01:30 in America/Los_Angeles is 2026-11-01 08:30:00 UTC or 2026-11-01 09:30:00 UTC, and the two choices name them that way. The supplied instant determines the initial selection, so a later occurrence is preserved. Editing the date or time clears that choice and requires choosing again before Apply.

Focus and accessibility

The labeled group contains separately labeled date and time controls. Radio choices identify both repeated-time instants. All errors remain visible as text. The id and forwarded HTMLDivElement ref identify a focusable group; focusing it enters the first date segment for error-summary navigation. Closing the date's calendar, with Escape or by choosing a day, returns focus to its calendar button. A required picker marks every date and time segment required for assistive technology and says once that a value is missing. When the application accepts Apply, focus stays on the picker's group instead of falling to the page. Disabled and read-only states prevent editing and Apply. The date and time fields sit side by side when the picker itself is wide enough for both, and stack into one column when it is not, whatever the window width.

The callback receives (valid, { pending }). Use valid to gate Review/Save and pending to track unfinished local editing for leave protection or draft persistence. A pristine required-empty field is invalid but has pending: false; partial input has pending: true. Malformed supplied values also remain clean until edited. Existing callbacks that accept only valid continue to work.

Props

PROPTYPEDEFAULTREQUIRED
labelstring—yes
value

Integer epoch milliseconds, or null. Untouched values retain their supplied seconds and milliseconds.

number—yes
timeZone

IANA time zone used to display and resolve the wall-time draft. Visible beside the fields.

string—yes
onValueChange

Requests an instant or null only after Apply. Minute-level edits commit with zero seconds and milliseconds.

function—yes
onDraftValidityChange

Callback (valid, { pending }). Pending identifies uncommitted local edits; pristine required-empty or malformed supplied values are invalid but not pending. False for invalid, incomplete, or unapplied edits. Returns true when the host accepts Apply or supplies another valid value. Block Review/Save while false.

function—no
min

Inclusive epoch-millisecond lower bound.

number—no
max

Inclusive epoch-millisecond upper bound.

number—no
disabledbooleanfalseno
readOnlybooleanfalseno
requiredbooleanfalseno
id

ID of the focusable group. Focusing it or its forwarded HTMLDivElement ref enters the first date segment.

string—no
classNamestring—no

Manifest entry

<DateTimePicker id="window-start" label="Window start" value={instant} timeZone="America/Los_Angeles" onValueChange={setInstant} onDraftValidityChange={setInstantValid} required />
View agent manifest
{
  "description": "Controlled instant editor with an explicit IANA time zone, minute-level date/time drafts, Apply, and explicit daylight-saving overlap choices.",
  "props": {
    "label": {
      "type": "string",
      "required": true
    },
    "value": {
      "type": "number",
      "required": true,
      "description": "Integer epoch milliseconds, or null. Untouched values retain their supplied seconds and milliseconds."
    },
    "timeZone": {
      "type": "string",
      "required": true,
      "description": "IANA time zone used to display and resolve the wall-time draft. Visible beside the fields."
    },
    "onValueChange": {
      "type": "function",
      "required": true,
      "description": "Requests an instant or null only after Apply. Minute-level edits commit with zero seconds and milliseconds."
    },
    "onDraftValidityChange": {
      "type": "function",
      "description": "Callback (valid, { pending }). Pending identifies uncommitted local edits; pristine required-empty or malformed supplied values are invalid but not pending. False for invalid, incomplete, or unapplied edits. Returns true when the host accepts Apply or supplies another valid value. Block Review/Save while false."
    },
    "min": {
      "type": "number",
      "description": "Inclusive epoch-millisecond lower bound."
    },
    "max": {
      "type": "number",
      "description": "Inclusive epoch-millisecond upper bound."
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "readOnly": {
      "type": "boolean",
      "default": false
    },
    "required": {
      "type": "boolean",
      "default": false
    },
    "id": {
      "type": "string",
      "description": "ID of the focusable group. Focusing it or its forwarded HTMLDivElement ref enters the first date segment."
    },
    "className": {
      "type": "string"
    }
  },
  "composable_with": [
    "FormSection",
    "FormErrorSummary",
    "DatePicker",
    "TimeField"
  ],
  "never_inside": [
    "Button"
  ],
  "example": "<DateTimePicker id=\"window-start\" label=\"Window start\" value={instant} timeZone=\"America/Los_Angeles\" onValueChange={setInstant} onDraftValidityChange={setInstantValid} required />"
}

On this page