demurrageClock
Signature
Section titled “Signature”demurrageClock(events: ClockEvent[], scope: ClockScope, options: ClockOptions): Interval | nullPick the two events a charge’s clock runs between.
-
No regulation or industry standard fixes these events; the carriers’ published tariffs agree on them (import: Maersk’s terms, CMA CGM’s general terms, Hapag-Lloyd, ACL; export: Maersk, CMA CGM, ACL), and DCSA’s glossary draws the line they rest on: demurrage is charged while the container is inside the terminal or depot, detention while it is outside, and storage is the charge for the terminal’s space, paid to the terminal or to the carrier on its behalf. Export storage (
gatedIn→loaded) follows from that storage definition; no tariff read quotes it. The merged clock runs demurrage and detention as one period, a named tariff product at Maersk (“Combined”), CMA CGM (“merged”) and MSC.demurrageClockselects the pair for the charge and direction asked for, so the wrong pair can never reachchargeableDays.scope import export demurrage,storagestartEvent→gatedOutgatedIn→loadeddetentiongatedOut→emptyReturnedemptyReleased→gatedIncombinedstartEvent→emptyReturnedemptyReleased→loaded -
directionhas no default. The same scope name selects different events on the import and export legs, and guessing it from the events present would be a silent guess. -
startEventis import only. It is not read for detention or export, so one options object can serve every scope on a leg. A tariff that starts at customs release (Hapag-Lloyd Japan) or ends export demurrage at the cut-off or the scheduled sailing passes that instant as the event’sat; GMT does not invent an event for one tariff. -
Events may be in any order, and every one must be
{ type, at }with a known type and a valid instant, used or not, with no holes in the array: a list with a bad entry is a bad list. -
The result is an
Interval, half-open[start, end), in the caller’s own strings, and feedschargeableDays(start, end, …)directly. -
Some tariffs differ in words, not events: MSC USA calls the in-terminal container charge “detention” and the out-of-terminal one “per diem”. GMT’s scope names follow the global usage.
-
Returns
nullwheneventsis not an array or holds an invalid event or a hole,scope,directionorstartEventis unknown,optionsis not an object, a required event is missing or occurs more than once (a container discharged twice is a data error, not a choice), or the end event precedes the start event.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
events | ClockEvent[] | the container’s events, { type, at }, type one of discharged, available, gatedOut, emptyReturned, emptyReleased, gatedIn, loaded |
scope | ClockScope | “demurrage” | “detention” | “storage” | “combined” |
Options
Section titled “Options”options
Which leg of the cycle the clock is on, and where an import clock starts
The options demurrageClock reads.
import type { ClockOptions } from "@northguild/gmt";| Option | Type | Default | Description |
|---|---|---|---|
direction | "import" | "export" (ClockDirection) | Required | The leg of the container’s cycle, "import" or "export"; required, because the same scope runs between different events in each. |
startEvent? | "discharged" | "available" (ClockStartEvent) | "discharged" | Where an import demurrage, storage or combined clock starts: "discharged", the classic definition, or "available" for tariffs that start at the availability date. Not read for export or detention. |
Returns
Section titled “Returns”{ start, end } of the requested clock, or null on invalid input
ClockEvent
Section titled “ClockEvent”A container event: what happened and the instant it happened.
import type { ClockEvent } from "@northguild/gmt";| Member | Type | Description |
|---|---|---|
type | "discharged" | "available" | "gatedOut" | "emptyReturned" | "emptyReleased" | "gatedIn" | "loaded" (ClockEventType) | What happened to the container, as one of the events a charging clock can start or end at. |
at | string | The instant it happened, as an ISO 8601 string: Z, an offset, or a bracketed zone. |
ClockEventType
Section titled “ClockEventType”The events a container’s charging clocks run between, named after the DCSA Track & Trace equipment events they correspond to (equipmentEventTypeCode with emptyIndicatorCode):
import type { ClockEventType } from "@northguild/gmt";"discharged" | "available" | "gatedOut" | "emptyReturned" | "emptyReleased" | "gatedIn" | "loaded"ClockScope
Section titled “ClockScope”Which charge is being clocked. combined is the merged demurrage-and-detention clock.
import type { ClockScope } from "@northguild/gmt";"demurrage" | "detention" | "storage" | "combined"ClockDirection
Section titled “ClockDirection”Which leg of the container’s cycle the clock is on.
import type { ClockDirection } from "@northguild/gmt";"import" | "export"ClockStartEvent
Section titled “ClockStartEvent”Where an import demurrage, storage or combined clock starts, when the tariff says so.
import type { ClockStartEvent } from "@northguild/gmt";"discharged" | "available"Related types
Section titled “Related types”Examples
Section titled “Examples”import { demurrageClock } from "@northguild/gmt/intermodal/calculate";
demurrageClock([{ type: "discharged", at: "2024-06-14T19:00:00Z" }, { type: "available", at: "2024-06-15T12:00:00Z" }, { type: "gatedOut", at: "2024-06-20T14:30:00Z" }, { type: "emptyReturned", at: "2024-06-27T09:00:00Z" }], "demurrage", { direction: "import" }) // { start: "2024-06-14T19:00:00Z", end: "2024-06-20T14:30:00Z" }