Container Dwell: Two Hours, Two Days
Container Dwell: Two Hours, Two Days
A container gates in at a New York terminal at 23:00 and gates out at 01:00. How many days of dwell does the terminal count?
The naive approach
// The naive approach: elapsed hours, rounded up to days
const gateIn = new Date("2024-06-15T23:00:00-04:00");
const gateOut = new Date("2024-06-16T01:00:00-04:00");
const hours = (gateOut.getTime() - gateIn.getTime()) / 36e5; // 2
const days = Math.ceil(hours / 24);
// 1 — but the terminal's bill says 2, and it is rightWatch it break
The naive approach silently produces wrong results — there is no GMT equivalent to demonstrate because the failure is not using GMT.
Why
Terminals, depots and yards do not charge by elapsed hours. They count the local calendar days the container was present, and this one was present on the 15th and on the 16th. Elapsed time divided by 24 can never see a midnight. `dwellTime` returns both answers: the exact elapsed duration, and `calendarDays`, the number of distinct local dates the half-open interval [entry, exit) touches in the terminal's own zone. The zone is what decides the count, which is why the same two instants can be one day in Amsterdam and two in New York.
The gmt approach
import { dwellTime } from "@northguild/gmt/transport";
dwellTime(
"2024-06-15T23:00:00-04:00[America/New_York]",
"2024-06-16T01:00:00-04:00[America/New_York]",
);
// { duration: "PT2H",
// enter: "2024-06-15T23:00:00-04:00[America/New_York]",
// exit: "2024-06-16T01:00:00-04:00[America/New_York]",
// calendarDays: 2 }
// The same two instants, counted where the box actually sat:
dwellTime("2024-06-16T03:00:00Z", "2024-06-16T05:00:00Z", "America/New_York").calendarDays; // 2
dwellTime("2024-06-16T03:00:00Z", "2024-06-16T05:00:00Z", "Europe/Amsterdam").calendarDays; // 1Same widget, working
Edit the exit above to 2024-06-16T00:00:00-04:00[America/New_York] and the count drops to
1: an exit exactly at local midnight does not touch the new day, because the interval is
half-open at the exit. Remove the zones and pass two Z instants with no third argument and
the result is null, because a day count has no meaning without a place. To see the same dwell
drawn on New York’s day grid, open it in the Dwell
Ledger.
The full rules are in Transport: Legs and Dwell.