Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/react-aria-components/src/HiddenDateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ export function useHiddenDateInput(props: HiddenDateInputProps, state: DateField
inputStep = 3600;
}

let dateValue = state.value == null ? '' : state.value.toString();
let dateValue = '';
if (state.value != null && 'toAbsoluteString' in state.value) {
dateValue = state.value.toAbsoluteString().replace('Z', '');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there will never be something after the Z?

Copy link
Member Author

@yihuiliao yihuiliao Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah there shouldn't. toAbsoluteString makes use of .toISOString() which formats the date as the following YYYY-MM-DDTHH:mm:ss.sssZ. see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString

/** Converts the date to an ISO 8601 formatted string in UTC. */
toAbsoluteString(): string {
return this.toDate().toISOString();
}

Copy link
Member

@devongovett devongovett Oct 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think toAbsoluteString would not quite be right, because it returns the date in UTC whereas datetime-local expects it to be in the user's local time zone.

Also for granularity="day", the value may still be a CalendarDateTime or ZonedDateTime, we only display the date. Formatting it as a string will produce a full date time where the browser will expect only a date.

Maybe what we should do is always convert it to a CalendarDate or CalendarDateTime before converting to a string, depending on the granularity.

dateValue = state.granularity === 'day' 
  ? toCalendarDate(state.value).toString() 
  : toCalendarDateTime('timeZone' in state.value ? toLocalTimeZone(state.value) : state.value).toString()

} else if (state.value != null) {
dateValue = state.value.toString();
}

let inputType = state.granularity === 'day' ? 'date' : 'datetime-local';

Expand Down
3 changes: 1 addition & 2 deletions packages/react-aria-components/stories/DateField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,7 @@ export const DateFieldAutoFill = (props) => (
{...props}
name="bday"
autoComplete="bday"
defaultValue={parseAbsoluteToLocal('2021-04-07T18:45:22Z')
}
defaultValue={parseAbsoluteToLocal('2021-04-07T18:45:22Z')}
data-testid="date-field-example">
<Label style={{display: 'block'}}>Date</Label>
<DateInput className={styles.field} data-testid2="date-input">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {action} from '@storybook/addon-actions';
import {Button, Calendar, CalendarCell, CalendarGrid, DateInput, DatePicker, DateRangePicker, DateSegment, Dialog, Form, Group, Heading, Input, Label, Popover, RangeCalendar, TextField} from 'react-aria-components';
import clsx from 'clsx';
import {Meta, StoryFn} from '@storybook/react';
import {parseAbsoluteToLocal} from '@internationalized/date';
import React from 'react';
import styles from '../example/index.css';
import './styles.css';
Expand Down Expand Up @@ -211,7 +212,7 @@ export const DatePickerAutofill = (props) => (
<Label>Name</Label>
<Input name="firstName" type="name" id="name" autoComplete="name" />
</TextField>
<DatePicker data-testid="date-picker-example" name="bday" autoComplete="bday" {...props}>
<DatePicker data-testid="date-picker-example" name="bday" autoComplete="bday" defaultValue={parseAbsoluteToLocal('2021-04-07T18:45:22Z')} {...props}>
<Label style={{display: 'block'}}>Date</Label>
<Group style={{display: 'inline-flex'}}>
<DateInput className={styles.field}>
Expand Down