Skip to content

fix(schedule): move a past-midnight close stamped with the opening date to the next day - #697

Merged
cubehouse merged 1 commit into
mainfrom
fix/past-midnight-close-rollover
Nov 1, 2026
Merged

cubehouse merged 1 commit into
mainfrom
fix/past-midnight-close-rollover

Conversation

@cubehouse

Copy link
Copy Markdown
Member

Problem

Some sources write a close that falls after midnight using the date the park opened. The result is a schedule day whose closingTime is at or before its openingTime:

Park Days Published Meant
Gardaland 31 Oct 2026 10:00 to 2026-10-31T00:00:00+01:00 open until midnight that night
Busch Gardens Tampa 21 event nights, Oct 2026 19:00 to 00:00 / 01:00, same date 00:00 / 01:00 the next morning
SeaWorld San Diego 7 event nights, Oct 2026 19:00 to 00:00, same date midnight that night
Walibi Rhône-Alpes 24 Oct 2026 19:00 to 01:00, same date 01:00 the next morning

Read literally, each of these is an empty window. A consumer that works out "open now" from the hours sees the park as closed for the whole open day.

Fix

  • New rollPastMidnightClose() in src/datetime.ts. It moves a close that sits less than 24 h before its open to the same wall-clock time on the next calendar day.
    • With the park's IANA timezone, the offset is recomputed, so a close on the night the clocks change gets the right one.
    • Without a timezone, the string's own offset is kept.
    • A close a full day or more before the open is left alone, since that isn't this shape.
  • Destination.getSchedules() applies it to every entry with times, for every park. That puts the fix in one place instead of in each framework's builder, so a new source with the same shape is covered too. The entry's date is unchanged.

Before/after

I applied the new pass to every park's currently published Oct-Nov 2026 schedule: 8,985 entries, of which exactly the 30 days in the table above change. No other entry moves.

Tests

src/__tests__/pastMidnightClose.test.ts covers:

  • the Gardaland and 01:00 event-night cases;
  • an offset recomputed across the October clock change;
  • the offset kept when no timezone is known;
  • normal days, unparseable times and day-early closes left alone;
  • a close equal to the open, read as a 24 h day;
  • getSchedules() rolling one entry while leaving the others as built.

The full suite passes: 188 files, 4,172 tests.

…te to the next day

Some sources write a close after midnight with the date the park opened, so
closingTime <= openingTime: Gardaland's 31 Oct 2026 late opening (10:00 to
"2026-10-31T00:00"), Busch Gardens Tampa and SeaWorld San Diego event nights
(19:00 to "00:00"/"01:00" the same date), Walibi Rhone-Alpes on 24 Oct. Read
literally each is an empty window, so anything deciding "open now" from the
hours sees the park closed through the whole open day.

getSchedules() now moves such a close forward one calendar day for every
park, recomputing the offset in the park's timezone. A close a full day or
more before the open is left alone. Over every park's published Oct-Nov 2026
schedule (8985 entries) exactly those 30 days change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cubehouse
cubehouse merged commit e0ff24f into main Nov 1, 2026
4 checks passed
@cubehouse
cubehouse deleted the fix/past-midnight-close-rollover branch November 1, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant