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

#!ek9
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: coalescing, compare, duration, iso8601, lesser, longer, operator, period, shorter, time