Skip to content

Commit f7c928e

Browse files
fix: parse holiday date strings as local time to prevent timezone shift
When holiday dates are provided as ISO date strings (YYYY-MM-DD), the previous implementation used `new Date(string)` which parses them as UTC midnight. This caused holidays to display on the wrong day in timezones west of UTC. For example, "2025-01-01" would be parsed as 2025-01-01T00:00:00.000Z, which when formatted in PST (UTC-8) becomes December 31st, 2024. This fix uses the existing `parseDate` utility with the ISO format, which uses date-fns's `parse` function that treats dates as local time. Fixes #6105 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 8279f2f commit f7c928e

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

src/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,10 +410,12 @@ export class DatePicker extends Component<DatePickerProps, DatePickerState> {
410410
: newDate();
411411

412412
// Convert the date from string format to standard Date format
413+
// Uses parseDate with ISO format to parse as local time, preventing
414+
// dates from shifting in timezones west of UTC. See issue #6105.
413415
modifyHolidays = () =>
414416
this.props.holidays?.reduce<HolidayItem[]>((accumulator, holiday) => {
415-
const date = new Date(holiday.date);
416-
if (!isValid(date)) {
417+
const date = parseDate(holiday.date, "yyyy-MM-dd", undefined, false);
418+
if (!date) {
417419
return accumulator;
418420
}
419421

src/test/datepicker_test.test.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5461,6 +5461,40 @@ describe("DatePicker", () => {
54615461
expect(container.querySelector(".react-datepicker")).not.toBeNull();
54625462
});
54635463

5464+
it("should apply holiday class to correct date regardless of timezone (issue #6105)", () => {
5465+
// This test verifies that holidays specified as ISO date strings (YYYY-MM-DD)
5466+
// are displayed on the correct date. The bug was that new Date("YYYY-MM-DD")
5467+
// parses as UTC midnight, causing dates to shift in western timezones.
5468+
const holidays = [{ date: "2024-01-15", holidayName: "Test Holiday" }];
5469+
5470+
const { container } = render(
5471+
<DatePicker
5472+
selected={new Date(2024, 0, 15)} // January 15, 2024 in local time
5473+
onChange={() => {}}
5474+
holidays={holidays}
5475+
inline
5476+
/>,
5477+
);
5478+
5479+
// Find the day element for January 15th and verify it has the holiday class
5480+
const jan15 = container.querySelector(
5481+
".react-datepicker__day--015:not(.react-datepicker__day--outside-month)",
5482+
);
5483+
expect(jan15).not.toBeNull();
5484+
expect(jan15?.classList.contains("react-datepicker__day--holidays")).toBe(
5485+
true,
5486+
);
5487+
5488+
// Verify January 14th does NOT have the holiday class (the bug would show it here)
5489+
const jan14 = container.querySelector(
5490+
".react-datepicker__day--014:not(.react-datepicker__day--outside-month)",
5491+
);
5492+
expect(jan14).not.toBeNull();
5493+
expect(jan14?.classList.contains("react-datepicker__day--holidays")).toBe(
5494+
false,
5495+
);
5496+
});
5497+
54645498
it("should handle deferFocusInput and cancelFocusInput", () => {
54655499
jest.useFakeTimers();
54665500

0 commit comments

Comments
 (0)