Skip to content

Commit

Permalink
[pickers] Fix DigitalClock time options on a DST switch day (@Luk…
Browse files Browse the repository at this point in the history
…asTy) (#15088)

Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
  • Loading branch information
github-actions[bot] and LukasTy authored Oct 24, 2024
1 parent 4c512d3 commit d4fe257
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
18 changes: 10 additions & 8 deletions packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,13 +274,14 @@ export const DigitalClock = React.forwardRef(function DigitalClock<TDate extends
);

const timeOptions = React.useMemo(() => {
const result: TDate[] = [];
const startOfDay = utils.startOfDay(valueOrReferenceDate);
return [
startOfDay,
...Array.from({ length: Math.ceil((24 * 60) / timeStep) - 1 }, (_, index) =>
utils.addMinutes(startOfDay, timeStep * (index + 1)),
),
];
let nextTimeStepOption = startOfDay;
while (utils.isSameDay(valueOrReferenceDate, nextTimeStepOption)) {
result.push(nextTimeStepOption);
nextTimeStepOption = utils.addMinutes(nextTimeStepOption, timeStep);
}
return result;
}, [valueOrReferenceDate, timeStep, utils]);

return (
Expand All @@ -301,9 +302,10 @@ export const DigitalClock = React.forwardRef(function DigitalClock<TDate extends
return null;
}
const isSelected = utils.isEqual(option, value);
const formattedValue = utils.format(option, ampm ? 'fullTime12h' : 'fullTime24h');
return (
<ClockItem
key={utils.toISO(option)}
key={`${(option as any).valueOf()}-${formattedValue}`}
onClick={() => !readOnly && handleItemSelect(option)}
selected={isSelected}
disabled={disabled || isTimeDisabled(option)}
Expand All @@ -314,7 +316,7 @@ export const DigitalClock = React.forwardRef(function DigitalClock<TDate extends
aria-selected={isSelected}
{...clockItemProps}
>
{utils.format(option, ampm ? 'fullTime12h' : 'fullTime24h')}
{formattedValue}
</ClockItem>
);
})}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,74 @@ describe('<DigitalClock /> - Timezone', () => {
expect(actualDate).toEqualDateTime(expectedDate);
});

it('should render correct time options when fall back DST occurs', () => {
render(
<DigitalClock
referenceDate={adapter.dateWithTimezone('2023-11-05T12:00:00', 'America/New_York')}
timezone="America/New_York"
timeStep={30}
/>,
);
const oneAM = adapter.setMinutes(
adapter.setHours(adapter.dateWithTimezone(undefined, 'default'), 1),
0,
);
const elevenPM = adapter.setMinutes(
adapter.setHours(adapter.dateWithTimezone(undefined, 'default'), 23),
0,
);
expect(
screen.getAllByText(
adapter.format(
oneAM,
adapter.is12HourCycleInCurrentLocale() ? 'fullTime12h' : 'fullTime24h',
),
),
).to.have.length(adapter.lib === 'dayjs' ? 1 : 2);
expect(
screen.getAllByText(
adapter.format(
elevenPM,
adapter.is12HourCycleInCurrentLocale() ? 'fullTime12h' : 'fullTime24h',
),
),
).to.have.length(1);
});

it('should contain time options until the end of day when spring forward DST occurs', () => {
render(
<DigitalClock
referenceDate={adapter.dateWithTimezone('2024-03-10T12:00:00', 'America/New_York')}
timezone="America/New_York"
timeStep={30}
/>,
);
const startOfDay = adapter.setMinutes(
adapter.setHours(adapter.dateWithTimezone(undefined, 'default'), 0),
0,
);
const eleven30PM = adapter.setMinutes(
adapter.setHours(adapter.dateWithTimezone(undefined, 'default'), 23),
30,
);
expect(
screen.getAllByText(
adapter.format(
startOfDay,
adapter.is12HourCycleInCurrentLocale() ? 'fullTime12h' : 'fullTime24h',
),
),
).to.have.length(1);
expect(
screen.getAllByText(
adapter.format(
eleven30PM,
adapter.is12HourCycleInCurrentLocale() ? 'fullTime12h' : 'fullTime24h',
),
),
).to.have.length(1);
});

TIMEZONE_TO_TEST.forEach((timezone) => {
describe(`Timezone: ${timezone}`, () => {
it('should use timezone prop for onChange when no value is provided', () => {
Expand Down

0 comments on commit d4fe257

Please sign in to comment.