multimodalETA
Signature
Section titled “Signature”multimodalETA(legs: Leg[], options?: ScheduleDeliveryOptions): MultimodalJourney | nullCompute an end-to-end ETA across the legs of a multimodal move, and report the time in transit and the time in dwell separately.
- A truck→ship→rail move spends its time two ways: moving, and sitting at a handoff. The two are forecast differently and fail differently, so one opaque total hides the part a planner needs.
multimodalETAschedules the legs withscheduleDeliveryand splits the elapsed time from the first departure to the ETA into the two. - The legs are
scheduleDelivery’s. Each leg’s arrival plus itsdwellAfteris the next leg’s departure unless the next leg names a scheduleddeparture; a scheduled departure inside the dwell is a missed connection. Departures, zones and every validity rule are that function’s, andetais itseta. - Local-time resolution policy (
"compatible"), asscheduleDeliveryapplies it. A zoneless first departure read instartTimeZone, a zoneless later-leg departure read in the previous leg’stimeZone, and a zoned departure written without an offset are wall times. An ambiguous one (a fall-back hour the clock ran through twice) resolves to the earlier instant and a nonexistent one (a spring-forward hour the clock skipped) to the later instant, except that on any leg but the first a repeated hour takes the earliest pass at or after the previous arrival plus its dwell, the first the cargo can catch. Write the offset to pick a pass yourself. totalTransitis every leg’sdurationadded up. Durations are exact time: a day is 24 hours, and years, months and weeks returnnull. The sum is elapsed time, so a leg across a DST change counts the hours that passed, not the change in the wall clock.totalDwellis the time actually spent at the handoffs: each leg’s departure minus the previous leg’s arrival. When every leg after the first chains from its predecessor, that is the sum of thedwellAftervalues. When a leg waits for a scheduled departure, the wait is dwell too: the cargo is at the handoff either way. Dwell is never estimated; it is the caller’sdwellAfterand schedule.- Transit plus dwell is the elapsed time from the first departure to the ETA, exactly.
- The last leg’s
dwellAfteris not dwell. There is no handoff after it, so it moves nothing; it is still checked as a duration, asscheduleDeliverychecks it. - Both totals are ISO 8601 durations with hours as the largest unit (
"PT400H","PT2H15M"), ascrossingTimeanddwellTimereport elapsed time; they do not depend on any zone. - Each leg’s fields are read once, so the totals always agree with the schedule.
- An empty legs array returns
{ eta: "", totalLegs: 0, totalTransit: "PT0S", totalDwell: "PT0S" }. Returnsnullon invalid input: a non-array, a malformed leg, a missed connection, an invalidstartTimeZone, or an arrival outside the instant range. - An offset with seconds (
-00:44:30) as a leg’stimeZoneor asstartTimeZonereturnsnull, as inscheduleDelivery. A written zone cannot carry seconds (RFC 9557 §4.1), soetacould not name it. Pass the IANA name.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
legs | Leg[] | the journey’s legs, in travel order |
Options
Section titled “Options”options
The zone a zoneless first-leg departure is read in
Type: ScheduleDeliveryOptions.
| Option | Type | Default | Description |
|---|---|---|---|
startTimeZone? | string | None. A zoneless first-leg departure is invalid input. | The time zone a zoneless first-leg departure is read in, an IANA name or a UTC offset to the minute (what isValidTimeZone accepts), for schedules published as local wall times. An ambiguous wall time resolves to the earlier instant and a nonexistent one to the later instant ("compatible"). Ignored when the first departure is already exact; never applied to later legs. |
Returns
Section titled “Returns”the ETA, the number of legs, and the total transit and dwell, or null on invalid input
MultimodalJourney
Section titled “MultimodalJourney”What multimodalETA returns: the end-to-end ETA, with the time moving and the time waiting kept apart.
import type { MultimodalJourney } from "@northguild/gmt";| Member | Type | Description |
|---|---|---|
eta | string | The last leg’s arrival rendered in its timeZone, as scheduleDelivery gives it. "" only for an empty legs array. |
totalLegs | number | The number of legs in the journey. |
totalTransit | string | The time the cargo spent moving: every leg’s duration added up, as an ISO 8601 duration of elapsed time with hours as the largest unit. |
totalDwell | string | The time the cargo spent at the handoffs between legs: each leg’s departure minus the previous leg’s arrival, added up, in the same form as totalTransit. It includes any wait for a scheduled departure on top of the handoff’s dwellAfter. |
Related types
Section titled “Related types”Examples
Section titled “Examples”import { multimodalETA } from "@northguild/gmt/intermodal/calculate";
multimodalETA([{ departure: "2024-06-10T08:00:00+08:00[Asia/Shanghai]", duration: "PT6H", timeZone: "Asia/Shanghai", dwellAfter: "P2D" }, { duration: "P14DT6H", timeZone: "America/Los_Angeles", dwellAfter: "PT36H" }, { duration: "PT52H", timeZone: "America/Chicago" }]) // { eta: "2024-06-29T23:00:00-05:00[America/Chicago]", totalLegs: 3, totalTransit: "PT400H", totalDwell: "PT84H" } (truck, ship and rail: 484 hours door to door)