mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.54k stars 1.32k forks source link

[pickers] onChange value's UTCness aren't consistent to what is set in `referenceDate` when initial value is entered via keyboard (no `defaultValue` or `value` set) #14809

Open kealjones-wk opened 1 month ago

kealjones-wk commented 1 month ago

Steps to reproduce

Link to live example: https://stackblitz.com/edit/react-6ictmq?file=Demo.tsx

Steps:

  1. Click the trigger to open the date calendar and click a date. Notice that the "Stored value" IS UTC.
  2. Refresh the page and use the keyboard to enter a date. Notice that the "Stored value" is NOT UTC.

Current behavior

Using referenceDate with a UTC dayjs object doesn't return UTC values in onChange when the initial method of entry is via keyboard. However if you click a date first, THEN clear it out and use the keyboard the UTC ness is persisted.

Expected behavior

When using a referenceDate that is UTC i expect that the values i get in onChange to be in UTC, just like i do when using value or defaultValue as UTC.

Context

I am trying to get a DatePicker to use UTC when there is no defaultValue or value. I realize i could use the timezone plugin but i only want to use UTC and don't want the extra bloat of the timezone plugin.

Theory: I assume that what is happening is that as you start typing the date the component's internal value get set to an Invalid Date dayjs representation and this dayjs object is NOT constructed or marked as being "UTC" like new values are, which then forces the component into using local timezone instead of UTC since it is the first "value". the lack of UTCness on an Invalid Date is probably related to this.

Your environment

No response

Search keywords: referenceDate, UTC, timezone, local Order ID: 82849

kealjones-wk commented 1 month ago

I just read through the code for AdapterDayJs and found that the timezone prop will actually not throw but only for UTC or system which i didn't see anywhere in the docs so when i was trying to use it with utc (lowercase) it would throw. So i have a workaround but it would be nice to get those 2 values explicitly documented somewhere (unless it is and i just missed it, i was looking around here)

flaviendelangle commented 1 month ago

I just read through the code for AdapterDayJs and found that the timezone prop will actually not throw but only for UTC or system

Where did you see that?

kealjones-wk commented 1 month ago

So to be clear, my original "bug report" here was that new values wouldn't persist UTCness using referenceDate when entered via a keyboard (when there was no value or defaultValue). The ability to use the timezone prop with "UTC" essentially works around that issue so I am good, i had mentioned in the above report that i didn't want to include the whole timezone plugin because i had tried using the timezone prop with "utc" which throws instead of "UTC" which does not (my bad). To be fair the values are called out here: https://mui.com/x/react-date-pickers/timezone/#supported-timezones so that is kinda on me.

@flaviendelangle here: https://github.com/mui/mui-x/blob/master/packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts#L338-L369 any value besides "UTC" "default" and "system" (in that exact casing) will throw new Error(MISSING_TIMEZONE_PLUGIN);.

Id only say maybe it would be handy to just add that you can use system/default with the timezone prop without including the timezone plugin and that you can use UTC with the timezone prop if you include the UTC plugin to the Day.js and UTC (and others if it applies) docs?

flaviendelangle commented 1 month ago

We could add a dev warning when utc is passed, that seems to be a common-enough error and the consequences are not that easy to debug as you said.

For the correct usage, I do agree that if value and defaultValue are not defined but referenceDate is, the timezone from referenceDate should be used. I'll have a look at how hard it would be to make that change 👍