Skip to content

diffUnixAsDuration

diffUnixAsDuration(value1: string | number, value2: string | number, unit: keyof DurationLike | DateTimeUnit, options?: ({ epochUnit?: UnixUnit; timeZone?: string; } & RoundingOptions<DateTimeUnit> & DurationStringOptions)): string

Return the difference between two Unix timestamps as an ISO 8601 duration string, bridging to the duration namespace (see parseDuration, normalizeDuration).

  • Converts both epochs to a Temporal.ZonedDateTime in timeZone and uses its until() with largestUnit set to unit, then .toString(). Calendar units (days, weeks, months, years) are therefore measured on that zone’s wall clock — a 23-hour DST day is P1D — while time units are exact elapsed time. Temporal.Instant.until() is not used: it rejects every calendar largestUnit.
  • Unlike diffUnix, unit is a single unit (not an array) — an ISO duration string already expresses a full multi-unit breakdown via largestUnit alone, so there’s no array-of-units overload here.
  • Returns "" for invalid input (negative diffs are valid and render with a leading -). smallestUnit, roundingIncrement, and roundingMode control optional rounding of the underlying difference before it’s rendered, per Temporal’s DifferenceOptions — same as diffUnix. toStringSmallestUnit, fractionalSecondDigits, and toStringRoundingMode control the precision of the rendered string itself, per Temporal’s ToStringPrecisionOptions (mirroring parseDuration’s options) — kept separate from the .until() rounding options above because both option sets have colliding smallestUnit/roundingMode keys with different Temporal types.
  • Each value is a safe integer or a digit string ("1706659200000"); anything else is invalid.
  • Unit names may be singular or plural ("day" or "days"), as in Temporal.
  • 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 returns "". An offset to the minute has no such limit.
ParameterTypeDescription
value1string | numberfirst Unix epoch: a safe integer, or a string of optionally negative ASCII digits
value2string | numbersecond Unix epoch, in the same form and unit
unitkeyof DurationLike | DateTimeUnitDateTimeDurationUnit to use as the duration’s largestUnit

options

optional: how the epochs are read, how the difference is rounded and how the string is rendered; a non-object value (such as null) is invalid

OptionTypeDefaultDescription
epochUnit?"seconds" | "milliseconds" | "second" | "millisecond" (UnixUnit)"milliseconds"The unit the epoch values are counted in: "seconds" or "milliseconds", singular or plural. Any other value returns "".
timeZone?string"UTC"The time zone calendar units are measured in: an IANA name, a UTC offset (a time zone identifier such as +05:30, +0530 or -08, or a stored offset ±HH:MM[:SS], what getTimeZoneOffset returns), or "local" for the system time zone. An unknown zone returns "".
smallestUnit?DateTimeUnit | PluralUnit<DateTimeUnit>None. The difference is not rounded: Temporal uses the smallest unit the values have, "day" for dates and "nanosecond" otherwise.The smallest unit kept in the difference; anything smaller is rounded into it. It may not be larger than the largest unit asked for.
roundingIncrement?number1, Temporal’s default.The step the smallest unit is rounded to, so 15 with "minute" rounds to a quarter of an hour. For a time unit it must divide the next larger unit evenly and be smaller than it (15 or 30 minutes, not 7 or 60); a date unit takes any whole number from 1 up. A non-integer is truncated first, as Temporal does, and any other value is invalid input.
roundingMode?"ceil" | "floor" | "expand" | "trunc" | "halfCeil" | "halfFloor" | "halfExpand" | "halfTrunc" | "halfEven""trunc", Temporal’s default for a difference.Which way a value between two steps goes. "trunc" rounds toward zero and "halfExpand" to the nearest step, a half going away from zero; the other modes are those of Temporal’s roundingMode option.
toStringSmallestUnit?SmallestUnit<"minute" | "second" | "millisecond" | "microsecond" | "nanosecond">None. The precision comes from fractionalSecondDigits.The smallest unit written in the string: "second", "millisecond", "microsecond" or "nanosecond". It sets how many fractional-second digits appear and takes precedence over fractionalSecondDigits. "minute" is refused, as Temporal.Duration refuses it.
fractionalSecondDigits?0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | "auto" | 8 | 9"auto", Temporal’s default.The number of fractional-second digits written: 0 to 9 writes exactly that many, and "auto" writes as many as the duration needs, with no trailing zeros. It has no effect when toStringSmallestUnit is given.
toStringRoundingMode?RoundingMode"trunc", Temporal’s default.How the duration is rounded when the precision asked for drops digits. "trunc" cuts them off; "halfExpand" rounds to the nearest value, a half going away from zero.

ISO 8601 duration string, or "" on invalid input

import { diffUnixAsDuration } from "@northguild/gmt/unix/calculate";
diffUnixAsDuration(1706659200000, 1706745600000, "days") // "P1D"
output 

unix/calculate/diffUnixAsDuration.ts