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 is the class
  - startDate <- Date() and gap <- Duration() are its two fields
  - startDate() and gap() are accessor methods for those fields
  - 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

#!ek9
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 sprintProject.endDate() < hotfix.endDate()
        stdout.println("Sprint project finishes before hotfix")

      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
      startDate <- Date()

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: add, arithmetic, class, constructor, date, duration, end date, operator plus, project