-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[pickers] DatePicker
character editing fails with timezone "Europe/London", Dayjs adapter
#13698
Comments
Hello @milotoor. |
DatePicker
character editing fails with timezone "Europe/London", Dayjs adapterDatePicker
character editing fails with timezone "Europe/London", Dayjs adapter
Ah, thanks for pointing that out! I tried out a modified version of the solution and it might workable, but I have a couple of concerns. The suggestion of doing this... export const getTimezone = (timestamp: number, timezone: string) => {
const isGMT = dayjs.tz(timestamp, timezone).offsetName() === 'GMT';
return isGMT ? 'UTC' : timezone;
}; ...doesn't seem fully applicable to the Additionally, regarding the specific bug I observed, it's not the selected timestamp (the start or end of the range) that matters--it's the end of the year. So in order for this solution to work the code would have to adjust to: const getTimezone = (timezone: string) => {
const isGMT = dayjs.tz(undefined, timezone).endOf('year').offsetName() === 'GMT'
return isGMT ? 'UTC' : timezone
}; That does fix the "I can't change the month with a numeric field edit" issue, but as you can see in the demo it causes issues for timestamps within the DST period (specifically every timestamp is moved back an hour, which impacts both the |
@LukasTy gentle ping 🔔 |
Hey @milotoor ... could you provide the code you entered to get that demo running? I cannot access it for some reason |
Strange, I can't access it either. Here's the original code: import dayjs, { type Dayjs } from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import * as React from 'react';
import { DemoContainer } from '@mui/x-date-pickers/internals/demo';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { DateTimeRangePicker } from '@mui/x-date-pickers-pro/DateTimeRangePicker';
import { DateRangePicker } from '@mui/x-date-pickers-pro/DateRangePicker';
import { Divider, Typography } from '@mui/material';
dayjs.extend(utc);
dayjs.extend(timezone);
export default function BasicDatePicker() {
const [range1, setRange1] = React.useState<[Dayjs | null, Dayjs | null]>([
dayjs.tz('2024-03-30', 'Europe/London'),
dayjs.tz('2024-04-01', 'Europe/London'),
]);
const [range2, setRange2] = React.useState<[Dayjs | null, Dayjs | null]>([
dayjs.tz('2024-10-26', 'Europe/London'),
dayjs.tz('2024-10-28', 'Europe/London'),
]);
const [range3, setRange3] = React.useState<[Dayjs | null, Dayjs | null]>([
dayjs.tz('2024-07-02', 'Europe/London'),
dayjs.tz('2024-07-05', 'Europe/London'),
]);
const [range4, setRange4] = React.useState<[Dayjs | null, Dayjs | null]>([
dayjs.tz('2024-11-26', 'Europe/London'),
dayjs.tz('2024-11-28', 'Europe/London'),
]);
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DemoContainer components={['DatePicker']}>
<Typography>Spans London DST (March 31st)</Typography>
<DateTimeRangePicker
value={range1}
onChange={(newValue) => setRange1(newValue)}
timezone="UTC"
/>
<DateRangePicker
value={range1}
onChange={(newValue) => setRange1(newValue)}
timezone="UTC"
/>
<Divider />
<Typography>Spans London DST (October 27th)</Typography>
<DateTimeRangePicker
value={range2}
onChange={(newValue) => setRange2(newValue)}
timezone="UTC"
/>
<DateRangePicker
value={range2}
onChange={(newValue) => setRange2(newValue)}
timezone="UTC"
/>
<Divider />
<Typography>Exclusively within DST</Typography>
<DateTimeRangePicker
value={range3}
onChange={(newValue) => setRange3(newValue)}
timezone="UTC"
/>
<DateRangePicker
value={range3}
onChange={(newValue) => setRange3(newValue)}
timezone="UTC"
/>
<Divider />
<Typography>Exclusively outside DST</Typography>
<DateTimeRangePicker
value={range4}
onChange={(newValue) => setRange4(newValue)}
timezone="UTC"
/>
<DateRangePicker
value={range4}
onChange={(newValue) => setRange4(newValue)}
timezone="UTC"
/>
<Divider />
<Typography>Uses "Europe/London", exclusively within DST</Typography>
<DateTimeRangePicker
value={range3}
onChange={(newValue) => setRange2(newValue)}
timezone="Europe/London"
/>
<DateRangePicker
value={range3}
onChange={(newValue) => setRange2(newValue)}
timezone="Europe/London"
/>
<Divider />
<Typography>Uses "Europe/London", exclusively outside DST</Typography>
<DateTimeRangePicker
value={range4}
onChange={(newValue) => setRange2(newValue)}
timezone="Europe/London"
/>
<DateRangePicker
value={range4}
onChange={(newValue) => setRange2(newValue)}
timezone="Europe/London"
/>
</DemoContainer>
</LocalizationProvider>
);
} |
Hey @milotoor are you bound to use DayJs? Considering the bug in the package this might be impossible to fix 100%, so I guess your best shot would be to switch to one of the other options. |
"Bound" is a strong word, but it would be a pretty large lift to drop Dayjs entirely from our application and probably not worth the effort for this reason alone. My strong preference would be to fix the library code, and I'm happy to contribute to that in whatever way I can. It looks like you opened a PR almost 10 months ago to fix the |
Thanks @milotoor ... I am not sure why the maintainer is not responding to this PR or even acknowledges that the issue is there ion the first place. 🤷🏼 |
@michelengelen I think this issue may actually have been fixed in Dayjs a couple of weeks ago! Their latest release (v1.11.12) includes a "Fix zero offset issue when use tz with locale" (see this PR), and I can confirm that updating to the latest version fixes the issue for me with the Thanks for your diligence working on this issue! I'm going to close it out since it appears to be resolved by updating Dayjs. |
@milotoor: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey. |
Steps to reproduce
Link to live example: https://react-t1mufn.stackblitz.io
Steps:
Current behavior
The input does not switch to the selected month, and appears to not respond to the character input whatsoever
Expected behavior
The
DatePicker
should switch to the selected monthContext
I am trying to use the "Europe/London" timezone with the
DatePicker
component (really theDateRangePicker
but the bug applies toDatePicker
, and I felt it would be simpler to illustrate the bug with the latter).After doing some digging through the source code, the issue appears to be Dayjs adapter code, probably its
adjustOffset
function used byendOfYear
. TheuseFieldCharacterEditing
hook performs range validations when applying a numeric edit. In this instance thesection.type
ismonth
, andsectionsValueBoundaries.month()
returns the dubious value of:The
month
function is defined here and returns amaximum
value ofutils.getMonth(endOfYear) + 1
, whereendOfYear
is defined asutils.endOfYear(today)
. Thus it seems that theendOfYear
orgetMonth
function is to blame. Of the two,endOfYear
seems the more likely as it is not simply calling dayjs library functions but also calls theadjustOffset
function. I have not dug into this further but suspect the issue lies in there.Interestingly this problem does not apply to other nearby timezones. For instance I have not experienced any issues with "Europe/Paris". Perhaps the proximity to UTC is relevant?
Your environment
npx @mui/envinfo
Note that my project is currently using
@mui/x-date-pickers-pro@6.19.9
but I have confirmed this bug exists on the latest stable version,7.8.0
, as seen in the attached minimal reproductionSearch keywords: DatePicker, timezone, Europe/London
Order ID: 87847
The text was updated successfully, but these errors were encountered: