fix(roadtrip): a check-in sets the hour when nothing before it does

Book a night to check in at ten, pin a stop to three in the afternoon behind it,
and the rail said 13:46. True enough as arithmetic — with no hour of its own the
chain works the first stop backwards out of the first one that has one, so three
minus a fourteen minute drive minus an hour standing there — and nothing anybody
asked for.

A door that opens at ten, with nothing ahead of it deciding otherwise, IS the
hour: the day starts there and runs forwards. Reached later it stays what it was,
a floor, and a floor below the arrival changes nothing — which is what keeps a
hotel behind an afternoon stop at its real arrival instead of dragging it back to
its check-in.
This commit is contained in:
Maurice
2026-09-13 16:22:07 +02:00
parent fcee6bd2c5
commit de3b2a6ac7
2 changed files with 23 additions and 3 deletions
+14
View File
@@ -865,6 +865,20 @@ describe('a check-in is a door opening, not an appointment', () => {
expect(schedule.warnings).toEqual([]);
});
it('sets the hour when nothing before it does, instead of being worked backwards', () => {
// Booked to check in at ten, with a stop pinned to three in the afternoon behind it.
// Read only as a floor, the chain worked the hotel backwards out of the afternoon
// and put it at 13:46: true enough as arithmetic, and nothing anybody asked for.
const schedule = computeSchedule(
[{ anchor: null, earliest: '10:00', dwellMinutes: 60 }, { anchor: '15:00', dwellMinutes: 60 }],
[14 * 60],
);
expect(schedule.entries[0]!.arrival).toBe('10:00');
expect(schedule.entries[0]!.anchored).toBe(true);
expect(schedule.entries[1]!.arrival).toBe('15:00');
expect(schedule.warnings).toEqual([]);
});
it('is simply arrived at when the drive gets there later', () => {
const schedule = computeSchedule(
[{ anchor: '15:00', dwellMinutes: 60 }, { anchor: null, earliest: '11:00', dwellMinutes: 60 }],
+9 -3
View File
@@ -199,10 +199,16 @@ export function computeSchedule(
// A door that opens at eleven is not an appointment at eleven. Reaching the stop
// later than that is simply reaching it; only a time somebody pinned can be missed.
const opens = parseClock(stop.earliest ?? null);
const waited = anchor === null && opens !== null && resolved.arrival !== null
? opens + Math.round((resolved.arrival - opens) / DAY_MINUTES) * DAY_MINUTES
// With nothing before it deciding the hour, the door IS the hour: a night booked
// to check in at ten starts the day at ten rather than being worked backwards out
// of whatever comes after it. Reached later, it is only a floor, and a floor below
// the arrival changes nothing.
const waited = anchor === null && opens !== null
? resolved.arrival === null
? opens + dayOffset * DAY_MINUTES
: opens + Math.round((resolved.arrival - opens) / DAY_MINUTES) * DAY_MINUTES
: null;
const held = waited !== null && waited > resolved.arrival!;
const held = waited !== null && (resolved.arrival === null || waited > resolved.arrival);
const arrival = held ? waited : resolved.arrival;
const lateBy = resolved.lateBy;
if (lateBy !== null) warnings.push({ index: i, code: 'late', minutes: lateBy });