Skip to content

Commit

Permalink
[pickers] Fix DigitalClock time options on a DST switch day (#10793)
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasTy authored Oct 24, 2024
1 parent 61bef1e commit 103c59c
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 8 deletions.
16 changes: 8 additions & 8 deletions packages/x-date-pickers/src/DigitalClock/DigitalClock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,13 +283,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]);

const focusedOptionIndex = timeOptions.findIndex((option) =>
Expand Down Expand Up @@ -348,10 +349,9 @@ export const DigitalClock = React.forwardRef(function DigitalClock<TDate extends
const formattedValue = utils.format(option, ampm ? 'fullTime12h' : 'fullTime24h');
const tabIndex =
focusedOptionIndex === index || (focusedOptionIndex === -1 && index === 0) ? 0 : -1;

return (
<ClockItem
key={formattedValue}
key={`${option.valueOf()}-${formattedValue}`}
onClick={() => !readOnly && handleItemSelect(option)}
selected={isSelected}
disabled={disabled || isTimeDisabled(option)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,71 @@ describe('<DigitalClock /> - Timezone', () => {
expect(actualDate).toEqualDateTime(expectedDate);
});

it('should render correct time options when fall back DST occurs', () => {
render(
<DigitalClock
referenceDate={adapter.date('2023-11-05T12:00:00', 'America/New_York')}
timezone="America/New_York"
timeStep={30}
/>,
);
const oneAM = adapter.setMinutes(adapter.setHours(adapter.date(undefined, 'default'), 1), 0);
const elevenPM = adapter.setMinutes(
adapter.setHours(adapter.date(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.date('2024-03-10T12:00:00', 'America/New_York')}
timezone="America/New_York"
timeStep={30}
/>,
);
const startOfDay = adapter.setMinutes(
adapter.setHours(adapter.date(undefined, 'default'), 0),
0,
);
const eleven30PM = adapter.setMinutes(
adapter.setHours(adapter.date(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 103c59c

Please sign in to comment.