Skip to content

crossingTime

  • Legs, dwell, cut-offs and punctuality, shared by road, rail, sea and air.
crossingTime(entry: string, exit: string, targetZone: string): Crossing | null

Measure a crossing — a canal transit, a strait passage, a border queue — and render both ends in the zone the crossing is administered in.

  • A crossing is logged as two instants, and the authority that schedules it reads both on its own clock. crossingTime returns the exact elapsed time between them plus the zone-local entry and exit. It deliberately counts no calendar days: dwell charged by local days (calendarDays) is dwellTime’s job, and a crossing that needs a day count is a dwell.
  • duration is exact elapsed time. A crossing spanning a DST transition reports the hours that actually elapsed; the local wall clocks at either end can be an hour apart from that. Hours is the largest unit, so the value never depends on a calendar.
  • targetZone is always the rendering zone. entry and exit are anything isValidInstant accepts — Z, an offset, or an offset with a bracketed zone — and only the instant is read: a bracketed zone in the input is never the zone the result is rendered in. That is the one contract difference from dwellTime, whose zone may come from its entry’s bracket.
  • The offset fixes each instant; a bracketed zone only resolves a rounded one. An offset written to the minute that is the bracketed zone’s sub-minute offset rounded (-00:45[Africa/Monrovia], for −00:44:30) names the instant the zone gives, as Temporal.ZonedDateTime.from reads it. A zone that does not exist, or that disagrees with the offset, is not checked and changes nothing.
  • targetZone is whatever isValidTimeZone accepts, which is what Temporal accepts: an IANA identifier, or a fixed offset such as "+02:00", which observes no DST.
  • GMT does not resolve a canal, lock or checkpoint code to a zone; the caller supplies the identifier.
  • Returns null when either instant is invalid, when exit is before entry (an inverted crossing is a data error, not a negative transit), or when the zone is invalid. A zero-length crossing is PT0S.
  • An offset with seconds (-00:44:30) returns null. A written zone cannot carry seconds (RFC 9557 §4.1), so the result could not name it. Pass the IANA name, or call fromOffsetInstant({ instant, offset }) for the local time with its full offset and no bracket.
ParameterTypeDescription
entrystringISO 8601 zoned datetime or instant string of entering the crossing
exitstringISO 8601 zoned datetime or instant string of leaving it
targetZonestringIANA name or a UTC offset to the minute (what isValidTimeZone accepts) the crossing is read in

exact duration and zone-local entry and exit, or null on invalid input

What crossingTime returns: exact elapsed time plus the local view at either end.

import type { Crossing } from "@northguild/gmt";
MemberTypeDescription
durationstringThe exact elapsed time from entry to exit, as an ISO 8601 duration with hours as the largest unit.
enterstringThe entry, rendered in the target zone.
exitstringThe exit, rendered in the target zone.
import { crossingTime } from "@northguild/gmt/transport/calculate";
crossingTime("2024-06-15T08:00:00Z", "2024-06-15T17:30:00Z", "Europe/Berlin") // { duration: "PT9H30M", enter: "2024-06-15T10:00:00+02:00[Europe/Berlin]", exit: "2024-06-15T19:30:00+02:00[Europe/Berlin]" }
output 

transport/calculate/crossingTime.ts