Skip to content

spanNs

spanNs(start: string, end: string): bigint | null

Return the exact elapsed nanoseconds between two ISO 8601 instant strings.

  • The precise form of spanMs, and the one to reach for past a number’s safe range.
  • Signed: negative when start is after end, so spanNs(b, a) is exactly -spanNs(a, b).
  • Measures exact elapsed time, never calendar distance. Across a DST transition “one day later” and “24 hours later” are different spans — spanWallClock answers the calendar question.
  • Accepts anything toNanoseconds does: the full RFC 9557 instant grammar, no leap seconds; calendar and elective annotations are ignored, as Temporal.Instant.from ignores them. An offset designator (Z, ±HH:MM) is required, optionally followed by a bracketed IANA zone — a bracket alone is not enough, which is the one string shape spanWallClock accepts and these two do not. The endpoints need not share a zone; an instant is an instant.
  • The offset fixes the 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, so a zoned string Temporal wrote is read back as the instant it was written for, except a wall time repeated inside a sub-minute offset change, which reads as its first pass (see isValidInstant). Otherwise the bracket is not checked: a zone that does not exist, or that disagrees with the offset, changes nothing. spanWallClock, by contrast, rejects a mismatched offset.
  • Returns null on invalid input, not 0n — 0n is the span between an instant and itself. This is why it does not simply subtract two toNanoseconds results, which return 0n for both the epoch and a rejected string.
  • The result is a duration, not an instant: it ranges up to ±17_280_000_000_000_000_000_000n, twice what Temporal.Instant can represent. Do not feed it to fromNanoseconds.
  • Leap seconds are not counted. UTC repeats a second rather than numbering a 61st one, so a span across one is a second short of the physical elapsed time; against a smeared clock (Google, AWS, Meta) the error is up to a second spread over the smear window. Leap-second-exact spans need a TAI scale, which GMT does not yet ship.
ParameterTypeDescription
startstringISO 8601 instant string the span is measured from
endstringISO 8601 instant string the span is measured to

exact elapsed nanoseconds as a bigint, negative when start is after end, or null on invalid input

import { spanNs } from "@northguild/gmt/span/calculate";
spanNs("2024-03-10T12:00:00Z", "2024-03-10T12:00:01Z") // 1000000000n
output 

span/calculate/spanNs.ts