How do I compare two durations and find the shorter one using coalescing?

← Operators and Expressions · Ref: Q1188

EK9 Duration uses ISO 8601 literal syntax and supports all comparison and coalescing operators.

DURATION LITERALS

  shortBreak <- PT15M       15 minutes
  longBreak <- PT1H         1 hour
  halfDay <- PT4H30M        4 hours 30 minutes
  threeDays <- P3D          3 days

COMPARISON

  if shortBreak < longBreak     shorter duration
  ordering <- shortBreak <=> longBreak

COALESCING

  shorter <- shortBreak <? longBreak   returns the shorter duration
  longer <- shortBreak >? longBreak    returns the longer duration

The <? operator handles unset values safely: if one side is unset, it returns whichever is valid.

See Q542 for temporal comparison. See Q243 for coalescing operators. See Q540 for duration arithmetic.

Example

defines module qa.operators.durationops

  defines function

    shorterOf() as pure
      ->
        left as Duration
        right as Duration
      <- rtn as Duration: left <? right

    longerOf() as pure
      ->
        left as Duration
        right as Duration
      <- rtn as Duration: left >? right

  defines program

    DurationOpsDemo()
      stdout <- Stdout()

      // === DURATION LITERALS (ISO 8601) ===

      shortBreak <- PT15M
      longBreak <- PT1H
      halfDay <- PT4H30M

      // === COMPARISON ===

      if shortBreak < longBreak
        stdout.println("Short break is shorter than long break")

      require shortBreak < longBreak
      require longBreak > shortBreak
      require shortBreak <> longBreak

      // === SPACESHIP ORDERING ===

      ordering <- shortBreak <=> longBreak
      stdout.println(`Short <=> Long: ${ordering}`)
      require ordering < 0

      // === COALESCING: FIND SHORTER AND LONGER ===

      shorter <- shorterOf(shortBreak, longBreak)
      longer <- longerOf(shortBreak, longBreak)
      stdout.println(`Shorter: ${shorter}`)
      stdout.println(`Longer: ${longer}`)
      require shorter == shortBreak
      require longer == longBreak

      // === HALF DAY COMPARISON ===

      require halfDay > longBreak
      require halfDay < PT5H
      stdout.println(`Half day: ${halfDay}`)

      // === STRING AND ISSET ===

      durStr <- $shortBreak
      stdout.println(`Duration string: ${durStr}`)
      require shortBreak?

      unsetDuration <- Duration()
      require ~unsetDuration?

Common mistakes

E50060 — Duration has no min() method, so left.min(right) is unresolved — use the <? coalescing operator to select the lesser value. See ek9 -h E50060 for details.

Incorrect:

left.min(right)

Correct:

left <? right
Other ways to ask this
  • Compare Duration values and pick the lesser using <? in EK9.
  • I need to select the shorter of two time periods for a break schedule.
  • In Java I used Duration.compareTo — what does EK9 use instead?

Coming from another language?

Java: Duration.compareTo(), no coalescing. Python: timedelta comparison with < >. Rust: Duration::cmp(). Go: time.Duration comparison with < >. EK9: ISO 8601 literals (PT15M, P3D), direct operators, <? coalescing for safe minimum selection.

Keywords: duration, shorter, time, longer, operator, lesser, period, compare, iso8601, coalescing