Calculate an end date from a start date and a duration gap on a Project class.

← Classes and OOP · Ref: Q1198

Define a class with Date and Duration fields, accessor methods, and a computed endDate() method. Use the + operator on Date to add Duration and get the end date.

CLASS WITH DATE AND DURATION

  Project
    startDate <- Date()
    gap <- Duration()
    startDate() accessor for the start date field
    gap() accessor for the duration field
    endDate() computes startDate + gap

DATE ARITHMETIC

  Date supports operator + with Duration, returning a new Date:
    endDate <- 2024-01-15 + P2M   gives a date 2 months later

This uses a class (not a record) because endDate() is a computed method. Records cannot have methods, only constructors and operators.

See Q1186 for date comparison. See Q1188 for duration operations. See Q1175 for record definition.

Example

defines module qa.classesandoop.projectenddate

  defines class

    Project
      startDate <- Date()
      gap <- Duration()

      default private Project() as pure

      Project() as pure
        ->
          theStart as Date
          theGap as Duration
        this.startDate :=: theStart
        this.gap :=: theGap

      startDate() as pure
        <- rtn as Date: Date(startDate)

      gap() as pure
        <- rtn as Duration: Duration(gap)

      endDate() as pure
        <- rtn as Date: startDate + gap

      default operator

  defines program

    ProjectEndDateDemo()
      stdout <- Stdout()

      // === PROJECT WITH 2-MONTH DURATION ===

      sprintProject <- Project(2024-01-15, P2M)
      stdout.println(`Sprint start: ${sprintProject.startDate()}`)
      stdout.println(`Sprint end: ${sprintProject.endDate()}`)

      // === PROJECT WITH 3-DAY DURATION ===

      hotfix <- Project(2024-06-01, P3D)
      stdout.println(`Hotfix start: ${hotfix.startDate()}`)
      stdout.println(`Hotfix end: ${hotfix.endDate()}`)

      // === PROJECT WITH 1-YEAR DURATION ===

      roadmap <- Project(2024-03-15, P1Y)
      stdout.println(`Roadmap start: ${roadmap.startDate()}`)
      stdout.println(`Roadmap end: ${roadmap.endDate()}`)

      // === COMPARE END DATES ===

      if hotfix.endDate() < sprintProject.endDate()
        stdout.println("Hotfix finishes before sprint project")

      if roadmap.endDate() > sprintProject.endDate()
        stdout.println("Roadmap extends beyond sprint project")

Common mistakes

E07290 — Records cannot have methods, only constructors and operators. Use a class when you need methods like endDate(). See ek9 -h E07290 for details.

Incorrect:

defines record
      Project
        endDate()
          <- rtn as Date: startDate + gap

Correct:

  defines class

    Project
      startDate <- Date()
Other ways to ask this
  • Define a Project with a start date and duration, then compute the end date.
  • I need a class that holds a Date and Duration and can calculate when the project finishes.
  • In Java I'd use LocalDate.plus(Period) — how does EK9 combine Date and Duration?
  • Given a project start date and a duration, show the projected completion date.

Coming from another language?

Java: LocalDate start; Period duration; start.plus(duration). Python: date + timedelta. Rust: NaiveDate + Duration (chrono). Go: t.Add(duration). EK9: startDate + gap — operator + on Date with Duration, no method calls.

Keywords: operator plus, class, end date, constructor, duration, date, project, arithmetic, add