Shopify / polaris

Shopify’s design system to help us work together to build a great experience for all of our merchants.
https://polaris.shopify.com
Other
5.71k stars 1.17k forks source link

[Date picker] Issues with local timezones #11139

Open jakearchibald opened 8 months ago

jakearchibald commented 8 months ago

Issue summary

function DatePickerExample() {
  return (
    <DatePicker
      month={10}
      year={2023}
      onChange={() => {}}
      onMonthChange={() => {}}
      selected={new Date('2023-11-08')}
    />
  );
}

Demo

I see this in the UK:

Screenshot 2023-11-08 at 10 56 03

Great! Ship it!

Whereas someone in the US would see:

Screenshot 2023-11-08 at 10 56 21

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 as date.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 selected YYYY-MM-DD in UTC.

Unfortunately neither of these changes are backwards compatible.

jakearchibald commented 7 months ago

If the implementation can't be fixed, the docs could offer guidance like: