How do I handle timezones in EK9?
← Date, Time, and Duration · Ref: Q541
DateTime is EK9's timezone-aware type. It always carries a timezone. Use withSameInstant() to convert between timezones for display, and withZone() to reinterpret the clock reading in a different zone.
TIMEZONE IN LITERALS
UTC: 2024-06-15T10:30:00Z (the Z suffix means UTC)
Offset: 2024-06-15T10:30:00-05:00 (five hours behind UTC)
Offset: 2024-06-15T10:30:00+05:30 (India Standard Time)
TIMEZONE ACCESSORS
zone() returns the timezone string: 'Z', '-05:00', '+05:30'
offSetFromUTC() returns the offset as a Duration: PT0S for UTC, PT-5H for -05:00
CONVERTING TIMEZONES
withSameInstant(zoneId) converts the DISPLAY to another timezone while preserving the actual moment in time. The clock reading changes but the instant stays the same:
utcMeeting <- 2024-06-15T10:30:00Z nyTime <- utcMeeting.withSameInstant('America/New_York') nyTime is 2024-06-15T06:30:00-04:00 (same instant, different clock)
withZone(zoneId) changes the timezone label WITHOUT converting the time. The clock reading stays but the instant changes:
labeled <- utcMeeting.withZone('America/New_York') labeled is 2024-06-15T10:30:00-04:00 (same clock, different instant)
See Q546 for a detailed comparison of withSameInstant vs withZone.
IANA TIMEZONE NAMES
EK9 supports standard IANA timezone names:
'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Australia/Sydney'
Also supports UTC offsets: 'UTC', 'UTC+5', 'UTC-8'
See Q545 for timezone conversion patterns. See Q547 for UTC storage best practices. See Q548 for comparing across timezones. See Q553 for common timezone mistakes.
Example
defines module qa.handle.timezones defines program HandleTimezonesDemo() stdout <- Stdout() // UTC literal utcMeeting <- 2024-06-15T10:30:00Z stdout.println(`UTC: ${utcMeeting}`) stdout.println(`Zone: ${utcMeeting.zone()}`) stdout.println(`Offset: ${utcMeeting.offSetFromUTC()}`) // Offset literals estEvent <- 2024-06-15T10:30:00-05:00 indiaEvent <- 2024-06-15T10:30:00+05:30 stdout.println(`EST: ${estEvent}, zone: ${estEvent.zone()}`) stdout.println(`IST: ${indiaEvent}, zone: ${indiaEvent.zone()}`) // withSameInstant: same moment, different clock nyTime <- utcMeeting.withSameInstant("America/New_York") tokyoTime <- utcMeeting.withSameInstant("Asia/Tokyo") londonTime <- utcMeeting.withSameInstant("Europe/London") stdout.println(`NY: ${nyTime}`) stdout.println(`Tokyo: ${tokyoTime}`) stdout.println(`London: ${londonTime}`) // withZone: same clock, different timezone label relabeled <- utcMeeting.withZone("America/New_York") stdout.println(`Relabeled: ${relabeled}`) // The key difference: // withSameInstant changes the clock to show the same moment // withZone keeps the clock and changes the timezone // So nyTime and relabeled show different times! stdout.println(`Same instant NY hour: ${nyTime.hour()}`) stdout.println(`Relabeled NY hour: ${relabeled.hour()}`) // Offset accessor returns Duration estOffset <- estEvent.offSetFromUTC() stdout.println(`EST offset: ${estOffset}`)
Common mistakes
E50060 — DateTime has no toTimezone() method. Use withSameInstant() to convert a DateTime to another timezone while preserving the same instant. See ek9 -h E50060 for details.
Incorrect:
nyTime <- utcMeeting.toTimezone("America/New_York")
Correct:
nyTime <- utcMeeting.withSameInstant("America/New_York")
Other ways to ask this
- How does EK9 handle timezone-aware dates?
- How do I create a DateTime with a specific timezone?
- What timezone formats does EK9 support?
Coming from another language?
Java: ZonedDateTime with ZoneId, withZoneSameInstant() and withZoneSameLocal() (confusing names). Python: datetime with pytz/zoneinfo, astimezone() for conversion. JavaScript: no built-in timezone support, Intl.DateTimeFormat or moment-timezone. Go: time.In(location) for conversion. Rust: chrono with_timezone(). EK9: DateTime built-in with zone(), withSameInstant() and withZone(), IANA names supported.
Keywords: withSameInstant, duration, offset, zone, iana, withZone, utc, time, convert, timezone, datetime