How do I add or subtract time from a date in EK9?
← Date, Time, and Duration · Ref: Q540
Use the + and - operators with Duration literals. EK9 supports both simple and compound assignment forms.
BASIC ARITHMETIC
nextWeek <- 2024-01-15 + P7D lastMonth <- 2024-06-15 - P1M meetingEnd <- 2024-06-15T10:00:00Z + PT1H30M
COMPOUND ASSIGNMENT
appointment <- 2024-03-01 appointment += P2W appointment -= P3D
INCREMENT AND DECREMENT
today <- Date().today() today++ today--
For Date, ++ adds one day and -- subtracts one day.
For DateTime, ++ and -- also add/subtract one day.
THE DURATION SUMMING PITFALL
Date + Duration is CALENDAR month arithmetic: it adds real calendar months and clamps to the month end. Because every step clamps, applying P1M twice is not the same as applying P2M once:
2024-01-31 + P1M gives 2024-02-29, clamped - February has no 31st 2024-01-31 + P1M + P1M gives 2024-03-29, clamping to Feb 29 and then adding a month 2024-01-31 + P2M gives 2024-03-31, one two-month calendar step
Month arithmetic on a Date is therefore NOT associative, exactly as in Java and Python.
A Duration on its own is flat: P1M + P1M re-normalises to P2M. So combine the durations first and apply them once:
2024-01-31 + (P1M + P1M) gives 2024-03-31
Step month by month only when stepwise clamping is what you mean.
For a specific day, construct the Date from components (see Q550 for the deep dive).
MILLISECOND ARITHMETIC
You can also add Millisecond values:
precise <- 2024-06-15T10:00:00Z + 5000ms
See Q32 for Duration literals. See Q539 for date subtraction. See Q550 for calendar edge cases and the full duration summing deep dive. See Q556 for Time wrapping.
Example
defines module qa.add.subtract.time defines program AddSubtractTimeDemo() stdout <- Stdout() // Basic date + duration start <- 2024-01-15 nextWeek <- start + P7D lastMonth <- start - P1M stdout.println(`Start: ${start}`) stdout.println(`+ P7D: ${nextWeek}`) stdout.println(`- P1M: ${lastMonth}`) // Complex duration future <- start + P1Y6M10D stdout.println(`+ P1Y6M10D: ${future}`) // Compound assignment appointment <- 2024-03-01 appointment += P2W stdout.println(`+ P2W: ${appointment}`) appointment -= P3D stdout.println(`- P3D: ${appointment}`) // Increment and decrement (one day) mutableDate <- 2024-06-15 mutableDate++ stdout.println(`After ++: ${mutableDate}`) mutableDate-- stdout.println(`After --: ${mutableDate}`) // DateTime arithmetic meeting <- 2024-06-15T10:00:00Z meetingEnd <- meeting + PT1H30M stdout.println(`Meeting end: ${meetingEnd}`) // Duration summing: Date + Duration clamps at the month end at EVERY step // so base + P1M + P1M (Feb 29, then Mar 29) differs from base + P2M (Mar 31) base <- 2024-01-31 sequential <- base + P1M + P1M combined <- base + P2M durationsFirst <- base + (P1M + P1M) stdout.println(`Sequential P1M + P1M: ${sequential}`) stdout.println(`Combined P2M: ${combined}`) stdout.println(`Durations first (P1M + P1M): ${durationsFirst}`) // Millisecond arithmetic precise <- 2024-06-15T10:00:00Z + 5000ms stdout.println(`+ 5000ms: ${precise}`) // Time arithmetic (wraps at 24h - see Q556) evening <- 22:00 lateNight <- evening + PT3H stdout.println(`22:00 + PT3H: ${lateNight}`)
Common mistakes
E50060 — Date has no plusDays() method. EK9 uses the + operator with Duration literals (P7D for 7 days) for date arithmetic. See ek9 -h E50060 for details.
Incorrect:
nextWeek <- start.plusDays(7)
Correct:
nextWeek <- start + P7D
Other ways to ask this
- How does date arithmetic work with Duration?
- How do I add days or months to a date?
- What is the duration summing pitfall?
Coming from another language?
Java: date.plusDays(7), date.plusMonths(1) calendar-safe but non-associative (Jan 31 + 1 month + 1 month differs from Jan 31 + 2 months). Python: timedelta(days=7) for days only, relativedelta for months (same non-associativity). JavaScript: manual setDate/setMonth (notoriously broken). Go: t.AddDate(0, 1, 0) calendar-safe but non-associative. EK9: date + P7D; Date + Duration is calendar-aware and clamps at the month end like Java, so it is not associative, while Duration + Duration is flat (P1M + P1M = P2M): combine the durations first, then apply once.
Keywords: duration, associative, calculate, migrate, summing, add, month, calendar, subtract, arithmetic, pitfall, increment, minus, date, clamping, plus, timezone, decrement, time