Skip to content

TimeZone

Standard library struct · Written TimeZone(“Europe/Paris”)

A TimeZone says where the clocks are. The same Instant shows different times in different places, and a zone is what turns the moment into the time on a particular wall.

const moment = Instant.parse("2026-09-25T14:30:00Z")
print(moment.to_date_time(TimeZone("Europe/Paris")))
print(moment.to_date_time(TimeZone("Asia/Kolkata")))
Output
2026-09-25T16:30:00
2026-09-25T20:00:00

Functions that need a zone take it as an optional zone, and use TimeZone.local, the computer’s own, when you give none. Two zones are equal when their names are, and a zone can be a dictionary key.

Making one
TimeZone(name), TimeZone.named_maybe(name) A zone by its name
TimeZone.utc Coordinated Universal Time
TimeZone.local The computer’s own zone
TimeZone.fixed(hours:, minutes:) A zone always the same distance from UTC
Reading
name The zone’s name
offset_at(instant) How far ahead of UTC the clocks are at a moment

TimeZone(name: String): TimeZone

A zone by name. Any zone in the IANA time zone database works, such as "America/New_York", "Europe/Paris", or "Asia/Kolkata", along with its whole history: New York kept its own local time until 1883, and Brazil stopped daylight time in 2019. Older names such as "US/Eastern" work too. "UTC" and an offset such as "+05:30" are names as well.

The database is built into Emerald, so a zone gives the same answer on every computer. Names are case-sensitive, as the database’s are:

try {
print(TimeZone("america/new_york"))
}
catch error: DateTimeError {
print(error.message)
}
Output
"america/new_york" is not a time zone Emerald knows: zone names are case-sensitive, so write "America/New_York"

Raises a DateTimeError for a name that isn’t a known zone.

TimeZone.named_maybe(name: String): TimeZone?

Like TimeZone(name), but gives nothing for an unknown name instead of raising an error. It suits a name a person typed.

print(TimeZone.named_maybe("Asia/Kolkata"))
print(TimeZone.named_maybe("Mars/Olympus"))
Output
Asia/Kolkata
nothing

TimeZone.utc: TimeZone

Coordinated Universal Time, the zone with no offset, named UTC.

print(TimeZone.utc)
Output
UTC

TimeZone.local: TimeZone

The computer’s own zone, worked out once when the program starts. It is the default wherever a zone is optional. emerald run reads it the way other programs on the computer do, from the TZ setting if there is one, and otherwise from the system’s own; if it can’t be found, the program uses UTC rather than stopping. emerald check, and the checks Emerald runs on itself, always use UTC, so they never depend on the computer.

TimeZone.fixed(hours: Int, minutes: Int = 0): TimeZone

A zone that is always this far from UTC, named by its offset. The minutes take the sign of the hours.

print(TimeZone.fixed(hours: 5, minutes: 30))
print(TimeZone.fixed(hours: -3, minutes: -30))
Output
+05:30
-03:30

A fixed zone isn’t the same as a place that happens to share its offset today, since a place can change its clocks. Use a named zone for a real place.

Raises a DateTimeError for minutes with the wrong sign or beyond 59, or an offset beyond 18 hours.

name: String

The zone’s name, which is also how it prints.

print(TimeZone("America/New_York").name)
Output
America/New_York

offset_at(instant: Instant): Duration

How far ahead of UTC the zone’s clocks are at a moment, as a Duration. Negative means behind. It changes through the year in a zone that changes its clocks:

const new_york = TimeZone("America/New_York")
print(new_york.offset_at(Instant.parse("2026-01-15T12:00:00Z")))
print(new_york.offset_at(Instant.parse("2026-07-15T12:00:00Z")))
Output
-5h
-4h