Module

Temporal.Duration

Package
purescript-temporal
Repository
philippedev101/purescript-temporal

Construction, arithmetic, and inspection of Duration values.

A Duration represents a length of time as a combination of date and time fields (years through nanoseconds). Key things to know:

  • Same-sign rule: all components must be zero or share the same sign. Constructing { years: 1, months: -1 } will fail.
  • Unbalanced by default: { hours: 36 } stays as-is and does not auto-convert to { days: 1, hours: 12 }. Use round to rebalance.
  • Eq is structural: hours 1.0 /= minutes 60.0 because Eq compares component-by-component, not total elapsed time.
  • Calendar operations need context: round, total, add, subtract, and compare may return Nothing (or throw) when calendar units (years, months, weeks) are involved and no relativeTo is provided, because their real-world length depends on a reference date.

#DurationFields Source

type DurationFields = { days :: Number, hours :: Number, microseconds :: Number, milliseconds :: Number, minutes :: Number, months :: Number, nanoseconds :: Number, seconds :: Number, weeks :: Number, years :: Number }

All fields of a Duration. Every field defaults to 0.0 — set only the fields you need.

All non-zero fields must share the same sign, or construction will fail.

#defaultDurationFields Source

defaultDurationFields :: DurationFields

All fields set to 0.0. Use record update syntax:

duration (defaultDurationFields { hours = 2.0, minutes = 30.0 })

#duration Source

duration :: DurationFields -> Maybe Duration

Construct a Duration from explicit fields. Returns Nothing if the fields have mixed signs (e.g. positive years with negative months).

#fromString Source

fromString :: String -> Maybe Duration

Parse an ISO 8601 duration string (e.g. "PT1H30M", "P1Y2M3D"). Returns Nothing for invalid strings.

Note: subsecond components are collapsed during serialization, so fromString (toString d) may produce a structurally different (but equal) duration. For example, { milliseconds: 1000 } serializes to "PT1S" and parses back as { seconds: 1 }.

#years Source

years :: Number -> Duration

Create a duration of the given number of years. Always succeeds for finite values.

#months Source

months :: Number -> Duration

Create a duration of the given number of months.

#weeks Source

weeks :: Number -> Duration

Create a duration of the given number of weeks.

#days Source

days :: Number -> Duration

Create a duration of the given number of days.

#hours Source

hours :: Number -> Duration

Create a duration of the given number of hours.

#minutes Source

minutes :: Number -> Duration

Create a duration of the given number of minutes.

#seconds Source

seconds :: Number -> Duration

Create a duration of the given number of seconds.

#milliseconds Source

milliseconds :: Number -> Duration

Create a duration of the given number of milliseconds.

#microseconds Source

microseconds :: Number -> Duration

Create a duration of the given number of microseconds.

#nanoseconds Source

nanoseconds :: Number -> Duration

Create a duration of the given number of nanoseconds.

#getMilliseconds Source

#getMicroseconds Source

#sign Source

sign :: Duration -> Int

The sign of the duration: 1 for positive, -1 for negative, 0 for blank.

#blank Source

blank :: Duration -> Boolean

Whether all fields are zero.

#add Source

add :: Maybe RelativeTo -> Duration -> Duration -> Maybe Duration

Add two durations. Returns Nothing if the result would have mixed signs.

When adding durations that contain calendar units (years, months, weeks), a relativeTo reference point is required to resolve the variable length of those units.

-- Time-only: no relativeTo needed
add Nothing (hours 1.0) (hours 2.0)  -- Just PT3H

-- Calendar units: provide a reference date
add (Just (RelDate someDate)) (months 1.0) (months 2.0)  -- Just P3M

#subtract Source

subtract :: Maybe RelativeTo -> Duration -> Duration -> Maybe Duration

Subtract one duration from another. Same caveats as add regarding calendar units and relativeTo.

#negated Source

negated :: Duration -> Duration

Return the duration with all component signs flipped. negated (negated d) == d for all durations.

#abs Source

abs :: Duration -> Duration

Return the duration with all components made non-negative. abs d == abs (negated d) for all durations.

#DurationRoundOptions Source

type DurationRoundOptions = { largestUnit :: DateTimeUnit, relativeTo :: Maybe RelativeTo, roundingIncrement :: Int, roundingMode :: RoundingMode, smallestUnit :: DateTimeUnit }

Options for round. The roundingIncrement must evenly divide the next-larger unit's maximum (e.g. for minutes: 1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30).

When relativeTo is Nothing, rounding fails for durations with calendar units. Provide a RelDate or RelDateTime for calendar-aware rounding, or a RelZoned for DST-aware rounding.

#round Source

round :: DurationRoundOptions -> Duration -> Maybe Duration

Round and/or rebalance a duration. Returns Nothing if the operation fails (e.g. calendar units without relativeTo).

To rebalance without rounding, set largestUnit to the desired largest unit:

-- Time-only rebalancing
round (defaultDurationRoundOptions { largestUnit = TimeU Hours }) (minutes 90.0)
-- Just PT1H30M

-- Calendar-aware rebalancing
round (defaultDurationRoundOptions
  { largestUnit = DateU Years
  , relativeTo = Just (RelDate someDate)
  }) (months 18.0)
-- Just P1Y6M

#DurationTotalOptions Source

type DurationTotalOptions = { relativeTo :: Maybe RelativeTo, unit :: DateTimeUnit }

Options for total.

When relativeTo is Nothing, computing the total fails for durations with calendar units. Provide a reference point to resolve calendar ambiguity.

#total Source

total :: DurationTotalOptions -> Duration -> Maybe Number

Compute the total duration in the given unit as a fractional number. Returns Nothing if the operation fails (e.g. calendar units without relativeTo).

-- Time-only
total { unit: TimeU Minutes, relativeTo: Nothing } (hours 1.0)
-- Just 60.0

-- Calendar-aware: "how many months is 45 days from Jan 1?"
total { unit: DateU Months, relativeTo: Just (RelDate jan1) } (days 45.0)
-- Just 1.5 (approximately)

#compare Source

compare :: RelativeTo -> Duration -> Duration -> Ordering

Compare two durations relative to a reference point, returning their ordering.

Unlike Eq (which compares component-by-component), compare resolves durations to actual elapsed time from the reference point. This means compare ref (days 30.0) (months 1.0) can determine which is longer for a specific starting date.

A relativeTo is always required because even time-only durations are compared via the Temporal spec's Duration.compare static method.

compare (RelDate jan1) (days 31.0) (months 1.0)  -- EQ (January has 31 days)
compare (RelDate feb1) (days 30.0) (months 1.0)  -- GT (February has 28 days)

#toString Source

toString :: Duration -> String

Serialize to an ISO 8601 duration string (e.g. "PT1H30M").

#zero Source

zero :: Duration

The zero duration (all fields 0). blank zero == true.

Re-exports from Temporal.Internal.Options

#RoundingMode Source

data RoundingMode

Rounding modes matching TC39 Temporal specification.

  • HalfExpand (default) — round half toward positive infinity ("normal" rounding)
  • Ceil — round toward positive infinity
  • Floor — round toward negative infinity
  • Trunc — round toward zero
  • Expand — round away from zero
  • HalfCeil — round half toward positive infinity
  • HalfFloor — round half toward negative infinity
  • HalfTrunc — round half toward zero
  • HalfEven — round half to even (banker's rounding)

Constructors

Instances

#RelativeTo Source

data RelativeTo

A reference point for calendar-aware Duration operations (round, total, add, subtract, compare).

  • RelDate — resolves calendar ambiguity (month/year lengths). All days are treated as exactly 24 hours. The duration is anchored at midnight.
  • RelDateTime — same as RelDate but anchored at the given wall-clock time, which affects how hours cross day boundaries.
  • RelZoned — resolves calendar ambiguity and DST. Days may be 23 or 25 hours near DST transitions.

Constructors

Instances

#DateUnit Source

data DateUnit

Units that apply only to date components.

Constructors

Instances

#DateTimeUnit Source

Re-exports from Temporal.Internal.Types

#ZonedDateTime Source

data ZonedDateTime

A date and time in a specific time zone, with full awareness of UTC offset and DST transitions (e.g. 2024-03-15T10:30:00-04:00[America/New_York]).

This is the richest Temporal type. Use it for scheduling future events where wall-clock time should be preserved even if DST rules change. For past events or timestamps, Instant is usually sufficient.

Instances

#PlainDateTime Source

data PlainDateTime

A calendar date and wall-clock time without a time zone (e.g. 2024-03-15T10:30:00).

Use PlainDateTime for events whose time zone is tracked separately, or for wall-clock displays. For unambiguous moments in time, use Instant or ZonedDateTime instead.

Instances

#PlainDate Source

data PlainDate

A calendar date without a time component or time zone (e.g. 2024-03-15).

Use PlainDate for birthdays, holidays, and other dates where time of day is irrelevant. Do not use for scheduling events — use ZonedDateTime instead.

Instances

#Duration Source

data Duration

A length of time expressed as a combination of date and time components (years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds). All components must share the same sign.

Durations are unbalanced{ hours: 36 } is not automatically converted to { days: 1, hours: 12 }. Use round to balance.

Eq compares component-by-component (not total elapsed time), so { hours: 1 } is not equal to { minutes: 60 }.

Instances