How do I compare two dates and determine which is earlier?

← Operators and Expressions · Ref: Q1186

EK9 Date values support all comparison operators directly. Use < > <= >= == <> for Boolean checks and <=> for Integer ordering.

DATE LITERALS

Write dates as YYYY-MM-DD:

  startDate <- 2024-01-15
  endDate <- 2024-06-30

COMPARISON

  if startDate < endDate          earlier date
  if startDate == endDate         same date
  ordering <- startDate <=> endDate  negative = earlier, zero = same, positive = later

COALESCING

  earlier <- startDate <? endDate   returns the earlier date
  later <- startDate >? endDate     returns the later date

No method calls like isBefore() or compareTo(). Operators work the same on Date as on Integer, String, or any other comparable type.

See Q542 for full temporal comparison. See Q238 for the complete operator set. See Q539 for date differences.

Example

defines module qa.operators.comparedates

  defines function

    <?- Compare two dates and return spaceship ordering. -?>
    compareDates() as pure
      ->
        left as Date
        right as Date
      <- rtn as Integer: left <=> right

    <?- Check if the first date is before the second. -?>
    isBefore() as pure
      ->
        left as Date
        right as Date
      <- rtn as Boolean: left < right

    <?- Return the earlier of two dates using coalescing min. -?>
    earlierOf() as pure
      ->
        left as Date
        right as Date
      <- rtn as Date: left <? right

    <?- Return the later of two dates using coalescing max. -?>
    laterOf() as pure
      ->
        left as Date
        right as Date
      <- rtn as Date: left >? right

  defines program

    CompareDatesDemo()
      stdout <- Stdout()

      // === DATE LITERALS ===

      startDate <- 2024-01-15
      endDate <- 2024-06-30
      midYear <- 2024-06-30

      // === COMPARISON VIA FUNCTION ===

      before <- isBefore(startDate, endDate)
      stdout.println(`Start before end: ${before}`)

      // === SPACESHIP ORDERING VIA FUNCTION ===

      ordering <- compareDates(startDate, endDate)
      stdout.println(`Start <=> End: ${ordering}`)

      sameCheck <- compareDates(endDate, midYear)
      stdout.println(`End <=> MidYear: ${sameCheck}`)

      // === COALESCING: FIND EARLIER AND LATER ===

      earlier <- earlierOf(startDate, endDate)
      later <- laterOf(startDate, endDate)
      stdout.println(`Earlier: ${earlier}`)
      stdout.println(`Later: ${later}`)

      // === SORTED DATE LIST VIA STREAM ===

      dates <- List() of Date
      dates += endDate
      dates += startDate
      dates += midYear

      sorted <- cat dates | sort | collect as List of Date
      stdout.println(`Sorted dates: ${sorted}`)

      // === STRING CONVERSION ===

      dateStr <- $startDate
      stdout.println(`Start date as string: ${dateStr}`)

      // === ISSET CHECK ===

      require startDate?
      unsetDate <- Date()
      require ~unsetDate?

Common mistakes

E50060 — Date has no isBefore() method — EK9 uses comparison operators (left < right) directly on temporal types. See ek9 -h E50060 for details.

Incorrect:

<- rtn as Boolean: left.isBefore(right)

Correct:

<- rtn as Boolean: left < right
Other ways to ask this
  • Compare two Date values and find which comes first in EK9.
  • I need to check whether a project start date is before the end date.
  • In Java I used isBefore() on LocalDate — what is the EK9 equivalent?

Coming from another language?

Java: LocalDate.isBefore(), compareTo(), isAfter() methods. Python: direct < > operators on datetime.date. Rust: PartialOrd on chrono::NaiveDate. Go: t.Before(), t.After() methods. Kotlin: compareTo() or operator overloading. EK9: direct < > <= >= == <> <=> operators on Date literals, no method calls needed.

Keywords: spaceship, later, operator, temporal, compare, before, ordering, date, after, coalescing, earlier