chargeableDays
Signature
Section titled “Signature”chargeableDays(clockStart: string, clockEnd: string, freeDays: number, options: FreeTimeChargeOptions): FreeTimeCharges | nullCount the days a container is charged for between the start of its clock and its exit, and list the dates behind the count.
- Lays out free time with the same walk as
freeTimeExpiry, then counts the days on or after the expiry that the half-open dwell[clockStart, clockEnd)touched. The result is the auditable form of a demurrage or detention charge:chargedDateslists the days behind the count, which is the list a day-numbered tariff grid is applied to, and the dates an itemised invoice can list. No regulation or industry standard fixes how the days are counted; every term below is the tariff’s. GMT computes days, never money:byTiersays how many days fell in each band so the caller can apply its rates. - Half-open at the exit. A day is charged when it started before
clockEnd, so a gate-out at exactlyexpiresAtis0chargeable days and one nanosecond later is1. A zero-length dwell touches the day it sits on, asdwellTimecounts. On the calendar basis withfirstDay: "eventDay",freeDaysUsed + chargeableDaysequalsdwellTime(...).calendarDays, with one exception: a fall-back that re-enters the day before the event day (America/Goose_Bay, 00:01 on 7 November 2010 back into the 6th) is a datedwellTimecounts as touched, and a tariff never counts a date before the event day. - The free-time terms are
freeTimeExpiry’s:basis,timeZone,firstDayandcalendarmean the same, andfirstDayhas no default. chargeBasissays how days after expiry are charged, and has no default. Many tariffs count free time and charges alike in calendar days. Where a tariff grants free time in working days, the days after it are mostly charged as calendar days, weekends and holidays included (Hapag-Lloyd’s tables: “Rate per Calendar day”; ACL: “Once free time expires … charged on calendar days”):basis: "working", chargeBasis: "calendar". Some tariffs charge working days only, for free time and charges alike, so neither counts a day the gate is closed or a holiday: both"working". Either"working"needscalendar. The two differ by every closed day after expiry, so neither is assumed.freeDaysmay be0for a tariff with no free time:expiresAtis the start of day one, the first day counted onbasis(under"nextDay", the first after the event day), and days before it are neither free nor charged.- Returns
nullwhen either instant is invalid,clockEndis beforeclockStart(an inverted dwell is a data error),freeDaysis not a whole number of at least0, the options fail as they do forfreeTimeExpiry,tiershas a hole, an unsafe integer or does not ascend, or the walk would pass 10,000 local days. - Limit at an offset with seconds. The instant is placed in the offset’s whole-minute zone, moved by its seconds, and the moved instant must be inside Temporal’s range. So within the offset’s seconds (under a minute) of the last instant Temporal supports (
+275760-09-13T00:00:00Z) for an offset east of UTC, or of the first (-271821-04-20T00:00:00Z) for one west, this returnsnull. An offset to the minute has no such limit.
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
clockStart | string | ISO 8601 instant string of the event that starts the clock |
clockEnd | string | ISO 8601 instant string of the event that stops it (gate-out or empty return) |
freeDays | number | whole number of free days the tariff allows, 0 or more |
Options
Section titled “Options”options
The tariff’s counting terms for free time and for charged days, and the tier bands
FreeTimeOptions plus how charged days are counted, and the optional tier boundaries.
import type { FreeTimeChargeOptions } from "@northguild/gmt";| Option | Type | Default | Description |
|---|---|---|---|
basis | "calendar" | "working" (FreeTimeBasis) | Required | Which days use up free time. "calendar" counts every local day, so a weekend burns two free days while the terminal is shut; "working" counts only the days calendar marks as working, and the clock does not run on weekends or holidays. |
timeZone | string | Required | The time zone of the terminal, depot or yard whose local midnight ends a day, an IANA name or UTC offset: a time zone identifier (+05:30, +0530, -08) or a stored offset (±HH:MM[:SS], what getTimeZoneOffset returns). GMT does not resolve a port or terminal code to a zone. A UTC offset such as "+02:00" observes no DST. |
firstDay | "eventDay" | "nextDay" (FreeTimeFirstDay) | Required | Where free time starts. "eventDay" makes the day of the event that starts the clock free day one; "nextDay" starts free time on the following counted day. |
calendar? | BusinessCalendar | None. A "working" basis without it is invalid input. | The terminal’s working week and holidays. It is required when a counting basis is "working" and not read otherwise. Its own timeZone is not used: timeZone above is the counting zone. |
chargeBasis | "calendar" | "working" (FreeTimeBasis) | Required | How days after expiry are charged: "calendar" charges every local day, "working" only the working days of calendar. No default; see chargeableDays. |
tiers? | number[] | None. byTier is the single open band { from: 1, to: null }. | The last chargeable-day ordinal of each band, as strictly ascending positive whole numbers: [5, 10] is days 1–5, 6–10 and 11 onward. They are day bands, not rates. Every band is returned, an empty one with days: 0, and the last is always open. |
Returns
Section titled “Returns”the free days used, the chargeable days, the expiry, the charged dates and the days per tier band, or null on invalid input
FreeTimeCharges
Section titled “FreeTimeCharges”What chargeableDays returns: the day count an invoice bills, and the dates that back it.
import type { FreeTimeCharges } from "@northguild/gmt";| Member | Type | Description |
|---|---|---|
freeDaysUsed | number | The number of free days the dwell touched, at most the tariff’s freeDays. |
chargeableDays | number | The number of counted days on or after expiresAt the dwell touched. |
expiresAt | string | The instant free time ended, as a UTC instant, as freeTimeExpiry reports it. |
chargedDates | string[] | The local dates charged, ascending. Carriers’ day-numbered tariff grids and progressive tiers are applied to this list, and its entries are the dates an itemised invoice can list. |
byTier | TierBand[] (TierBand) | The charged days split into the tiers bands; one open band when no tiers were given. |
TierBand
Section titled “TierBand”A band of chargeable-day ordinals and how many of the charged days fell in it.
import type { TierBand } from "@northguild/gmt";| Member | Type | Description |
|---|---|---|
from | number | The first chargeable-day ordinal of the band, from 1. |
to | number | null | The last ordinal of the band, or null for the open final band. |
days | number | The number of charged days that fell in the band. |
Related types
Section titled “Related types”Examples
Section titled “Examples”import { chargeableDays } from "@northguild/gmt/intermodal/calculate";
chargeableDays("2024-06-14T19:00:00Z", "2024-06-17T04:00:00Z", 3, { basis: "calendar", chargeBasis: "calendar", timeZone: "America/New_York", firstDay: "eventDay" }) // { freeDaysUsed: 3, chargeableDays: 0, expiresAt: "2024-06-17T04:00:00Z", chargedDates: [], byTier: [{ from: 1, to: null, days: 0 }] } (gate-out exactly at expiry is free)