Open jakearchibald opened 8 months ago
If the implementation can't be fixed, the docs could offer guidance like:
new Date('2023-11-08')
, do this: new Date(2023, 10, 08)
(note that the month is 0-indexed)onChange
returns dates at midnight in the user's local timezone. Ensure that the date is converted to a consistent timezone, or timezone data is removed, before sending to the server.
date.valueOf()
- this returns a timestamp of midnight in the user's local timezone. The server may be in a different timezone and interpret it as a different date.date.toISOString()
- this is a standard format, but it will convert to UTC, which may result in a different date than what the user selected.date.getUTC*
- UTC methods may result in a different date.date.toJSON()
(note, this is used automatically when converting dates to JSON) - This uses toISOString()
internally.date.toString()
- This will include the timezone, but the format is unusualdate.toDateString()
- This will only include the correct day, month, and year, but the format is unusual.date.getFullYear() + '-' + (date.getMonth() + 1).toString().padLeft(2, '0') + '-' + date.getDate().toString().padLeft(2, '0')
- This will return a string in the standard YYYY-MM-DD
ISO format without any dates shifting.
Issue summary
Demo
I see this in the UK:
Great! Ship it!
Whereas someone in the US would see:
This is because the Polaris date picker operates on the local system's view of dates, whereas
new Date('2023-11-08')
produces a UTC date.onChange
also produces dates in the user's timezone, so if they're sent to the server asdate.valueOf()
, the server may interpret the dates differently to how the user intended.Even weirder, thanks to daylight savings time, this component can produce a selected range where the start and end have different timezone offsets.
It's unlikely to happen in practice, but if users cross timezones while using this interface, weird things will happen.
The fundamental issue is the introduction of timezones when that isn't expressed in the UI. The user picks a
YYYY-MM-DD
, they don't pick a location, so involving data that depends on timezones introduces footguns.Ideally, the data that this component accepts and vends wouldn't express time & timezones. For example, a
YYYY-MM-DD
string. This is what<input type="date">
does.Another (less-good) option is to use dates, but base all calculations on UTC. Although this still has problems if the developer expects
new Date()
to represent today's date, as it might be different in UTC.valueAsDate
in<input type="date">
produces a date that's midnight of the selectedYYYY-MM-DD
in UTC.Unfortunately neither of these changes are backwards compatible.