How do I convert a DateTime to a different timezone in EK9?
← Date, Time, and Duration · Ref: Q545
Use withSameInstant(zoneId) to convert a DateTime to show the same moment in a different timezone. This is the most common timezone operation.
CONVERTING FOR DISPLAY
utcEvent <- 2024-06-15T14:00:00Z nyDisplay <- utcEvent.withSameInstant('America/New_York') tokyoDisplay <- utcEvent.withSameInstant('Asia/Tokyo') londonDisplay <- utcEvent.withSameInstant('Europe/London')
All three represent the SAME moment. Only the clock reading and timezone label change.
COMMON IANA ZONE NAMES
Americas: America/New_York, America/Chicago, America/Denver, America/Los_Angeles, America/Sao_Paulo Europe: Europe/London, Europe/Paris, Europe/Berlin, Europe/Moscow Asia: Asia/Tokyo, Asia/Shanghai, Asia/Kolkata, Asia/Dubai Pacific: Australia/Sydney, Pacific/Auckland UTC: UTC, Etc/UTC
PATTERN: STORE UTC, DISPLAY LOCAL
Store all timestamps in UTC. Convert to the user's timezone only for display:
stored <- 2024-06-15T14:00:00Z userZone <- 'America/New_York' displayed <- stored.withSameInstant(userZone)
This avoids timezone confusion in comparisons and arithmetic.
See Q541 for timezone basics. See Q546 for withSameInstant vs withZone. See Q547 for UTC storage best practices. See Q548 for cross-timezone comparison.
Example
defines module qa.convert.timezone defines program ConvertTimezoneDemo() stdout <- Stdout() // UTC event utcEvent <- 2024-06-15T14:00:00Z stdout.println(`UTC: ${utcEvent}`) // Convert to various timezones nyTime <- utcEvent.withSameInstant("America/New_York") chicagoTime <- utcEvent.withSameInstant("America/Chicago") laTime <- utcEvent.withSameInstant("America/Los_Angeles") londonTime <- utcEvent.withSameInstant("Europe/London") parisTime <- utcEvent.withSameInstant("Europe/Paris") tokyoTime <- utcEvent.withSameInstant("Asia/Tokyo") sydneyTime <- utcEvent.withSameInstant("Australia/Sydney") stdout.println(`New York: ${nyTime}`) stdout.println(`Chicago: ${chicagoTime}`) stdout.println(`Los Angeles: ${laTime}`) stdout.println(`London: ${londonTime}`) stdout.println(`Paris: ${parisTime}`) stdout.println(`Tokyo: ${tokyoTime}`) stdout.println(`Sydney: ${sydneyTime}`) // All are the same instant require nyTime == utcEvent require tokyoTime == utcEvent require sydneyTime == utcEvent stdout.println(`All equal UTC: ${nyTime == utcEvent and tokyoTime == utcEvent}`) // Store UTC, display local pattern stored <- 2024-12-25T00:00:00Z userZone <- "Europe/Berlin" displayed <- stored.withSameInstant(userZone) stdout.println(`Stored: ${stored}`) stdout.println(`User sees: ${displayed}`)
Common mistakes
E50060 — DateTime has no convertTo() method. Use withSameInstant() to convert a DateTime to show the same moment in a different timezone. See ek9 -h E50060 for details.
Incorrect:
nyTime <- utcEvent.convertTo("America/New_York")
Correct:
nyTime <- utcEvent.withSameInstant("America/New_York")
Other ways to ask this
- How do I display a time in a different timezone?
- How do I convert UTC to local time in EK9?
- How does withSameInstant work for timezone conversion?
Coming from another language?
Java: dateTime.withZoneSameInstant(ZoneId.of('America/New_York')). Python: dt.astimezone(zoneinfo.ZoneInfo('America/New_York')). JavaScript: no built-in, Intl.DateTimeFormat for display only. Go: t.In(loc). Rust: chrono with_timezone(). EK9: dateTime.withSameInstant('America/New_York') clear and concise.
Keywords: timezone, local, zone, duration, convert, display, time, iana, withSameInstant, utc