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
#!ek9 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: convert, datetime, duration, iana, offset, time, timezone, utc, withSameInstant, withZone, zone