How does Time wrapping work in EK9?
← Date, Time, and Duration · Ref: Q556
Time wraps at the 24-hour boundary. Adding time past midnight wraps to the next day's time. Time is a circular clock, not a linear timeline.
BASIC WRAPPING
pastMidnight <- 22:00 + PT3H // 01:00, wraps past midnight lastNight <- 01:00 - PT3H // 22:00, wraps backwards past midnight
Time always stays within 00:00:00 to 23:59:59.
WHY WRAPPING
Time represents a position on the clock face, not an absolute point in time. A clock does not stop at midnight; it wraps to 00:00. This models the real world correctly: if it is 22:00 and you wait 3 hours, the clock shows 01:00.
WRAPPING WITH INCREMENT/DECREMENT
lateNight <- 23:59:59 lateNight++ // wraps to 00:00:00 early <- 00:00:00 early-- // wraps to 23:59:59
WRAPPING AND SUBTRACTION
Subtracting a later time from an earlier time produces a negative Duration:
gap <- 01:00 - 22:00 // PT-21H, not PT3H
This is the linear difference, not the 'clock distance'.
DATETIME DOES NOT WRAP
DateTime (which includes a date) does NOT wrap. Adding PT3H to a DateTime at 22:00 moves to 01:00 on the NEXT DAY. The date changes.
WHEN TO USE TIME VS DATETIME
Time: schedules, recurring daily events, clock positions.
DateTime: events with specific dates, timestamps, logging.
See Q31 for Time basics. See Q540 for date arithmetic. See Q539 for time subtraction. See Q550 for calendar edge cases.
Example
#!ek9 defines module qa.time.wrapping defines program TimeWrappingDemo() stdout <- Stdout() // Basic wrapping past midnight evening <- 22:00 pastMidnight <- evening + PT3H stdout.println(`22:00 + PT3H = ${pastMidnight}`) // Wrapping backwards past midnight earlyMorning <- 01:00 lastNight <- earlyMorning - PT3H stdout.println(`01:00 - PT3H = ${lastNight}`) // Wrapping with larger durations noon <- 12:00 plusDay <- noon + PT24H stdout.println(`12:00 + PT24H = ${plusDay}`) plusDayHalf <- noon + PT36H stdout.println(`12:00 + PT36H = ${plusDayHalf}`) // Increment wrapping via duration almostMidnight <- 23:59:59 almostMidnight += PT1S stdout.println(`23:59:59 + 1s = ${almostMidnight}`) // Decrement wrapping via duration justPastMidnight <- 00:00:00 justPastMidnight -= PT1S stdout.println(`00:00:00 - 1s = ${justPastMidnight}`) // Subtraction gives linear difference (not clock distance) negGap <- 01:00 - 22:00 stdout.println(`01:00 - 22:00 = ${negGap}`) posGap <- 22:00 - 01:00 stdout.println(`22:00 - 01:00 = ${posGap}`) // DateTime does NOT wrap - date advances instead eveningDT <- 2024-06-15T22:00:00Z nextDayDT <- eveningDT + PT3H stdout.println(`DateTime 22:00 + 3h = ${nextDayDT}`) // The date changes from June 15 to June 16 stdout.println(`Day changed: ${nextDayDT.day()}`) // startOfDay and endOfDay dayStart <- Time().startOfDay() dayEnd <- Time().endOfDay() stdout.println(`Start of day: ${dayStart}`) stdout.println(`End of day: ${dayEnd}`)
Common mistakes
E50001 — EK9 has no static field access like Java's Time.MIN or Time.MAX. Type names without () are not resolved as expressions. Use Time().startOfDay() and Time().endOfDay() factory methods. See ek9 -h E50001 for details.
Incorrect:
dayStart <- Time.MIN dayEnd <- Time.MAX
Correct:
dayStart <- Time().startOfDay() dayEnd <- Time().endOfDay()
Other ways to ask this
- What happens when Time goes past midnight?
- Does Time wrap around at 24 hours?
- How does Time arithmetic handle overflow?
Coming from another language?
Java: LocalTime wraps at midnight (plusHours past midnight wraps). Python: time does not support arithmetic (must use datetime). JavaScript: no Time type, Date wraps dates. Go: no separate Time type, time.Time includes date. Rust: chrono NaiveTime wraps at midnight. EK9: Time wraps at 24h boundary, DateTime does not wrap (date advances).
Keywords: 24 hour, arithmetic, circular, clock, duration, midnight, overflow, time, timezone, wrap, wrapping