TimeZone

A TimeZone object represents a local time zone. It works with the Date class to convert between local time zones and universal time (UTC) when parsing, displaying, and manipulating dates and times.

In most cases, you won't need to use the TimeZone object directly, even if you use Date objects, because you'll usually want to work in terms of the host computer's local time zone. That's the default that Date uses for local/UTC conversions, so you don't have to use TimeZone objects in this case. The TimeZone object is only needed when you want to use a specific time zone for local/UTC conversions.

TimeZone uses the IANA zoneinfo database (also known as the tz database or Olson database) to perform its conversions. The zoneinfo database contains a comprehensive history of local time settings for locations around the world. The TADS interpreter includes a compiled version of the information in the zoneinfo database, so this information is always available. This allows the TimeZone object to calculate historically accurate local times for particular dates in the past in specific locations, based on actual historical records, including zone realignments (some cities have switched time zones on one or more occasions) and the daylight savings rules in effect in different years. The TimeZone object can also calculate local times in the future by extrapolating the current daylight savings rules for a zone. The zoneinfo database isn't static; it's updated frequently, because the world's timezones are always being revised. The TADS version of the zoneinfo database is in a separate file that can be replaced as needed without updating the TADS interpreter itself.

When using the TimeZone class, #include <date.h> in your source files.

Construction

new TimeZone()

Creates a TimeZone object representing the host system's local time zone. On Windows, this obtains the timezone settings from the operating system, and maps the Windows zone identifier to a corresponding zoneinfo key, using the mapping specified in the Unicode CLDR. On most Unix systems, the "TZ" environment variable specifies the settings. (For best results on Unix, you should set TZ to the zoneinfo key you wish to use; for example, for US Eastern Time, set TZ=America/New_York.)

new TimeZone(zoneinfoName)

Creates a TimeZone object for the given location in the zoneinfo database, such as 'America/New_York' or 'Europe/London'.

When you create a TimeZone object based on a zoneinfo location, local time conversions using the object will take into account historical changes to the location's time zone definition, including realignments (for example, America/Detroit was originally on US Central Time, but switched to Eastern Time in 1915) and daylight savings changes. It also applies the current daylight savings rules for the zone (if any) to dates in the future. Parsing or formatting a date/time value will treat the local time appropriately for its date, so that it matches the wall clock actually in effect on that date in the given location.

new TimeZone('STD+ofs[DST[+ofs],start,end]')

This format creates a custom time zone. This bypasses the zoneinfo database and lets you define a timezone with a custom name, UTC offset, and daylight savings rule. Since this type of TimeZone isn't tied to a zoneinfo entry, it doesn't have any location or history information.

The syntax is modeled on the POSIX "TZ" environment variable syntax, with one important difference: we use the zoneinfo convention that that the UTC offset is negative if it's west of UTC, whereas TZ uses positive offsets west of UTC. So if you're copying a Unix TZ setting, reverse the signs on the offsets: Unix EST5EDT becomes 'EST-5EDT' for the TimeZone constructor.

The simplest form is an abbreviation plus an offset in hours. For example, 'PST-8' defines a zone called "PST" with an offset 8 hours ahead of (west of) UTC. This is equivalent to the current official definition of US Pacific Standard Time, so a TimeZone created this way lets you parse and format times in Pacific Standard Time year round, even when daylight time would normally be in effect.

The complete form includes the standard time name and offset, the daylight time name and offset, and the annual rules for when daylight time starts and ends in the zone. The daylight offset can be omitted, in which case it defaults to one hour ahead of standard time. If you do include it, specify the daylight offset from UTC, not the offset from standard time - so for US Eastern Time, you'd write EST-5EDT-4, or equivalently just EST-5EDT.

The syntax for the start and end strings can be one of the following:

All of the formats above can optionally be followed by "/time", where time is the time of day on a 24-hour clock. This can simply be the hour if the time is at the top of the hours, so "/3" means 3:00 AM, and "/0:30" means 12:30 AM. If the time is omitted, the default is 2:00 AM ("/2").

Example: the complete current definition of US Eastern Time is EST-5EDT-4,M3.2.0/2,M11.1.0/2: standard time is called EST, with a UTC offset of 5 hours west; daylight time is EDT at 4 hours west; daylight time starts at 2:00 AM on the second Sunday in March, and ends at 2:00 AM on the first Sunday in November. You could write this more compactly, relying on the defaults, as EST-5EDT,M3.2.0,M11.1.0.

If you specify both standard and daylight time in a zone, TimeZone will accept the string without the daylight time start/end rules, but without the rules the zone will always use standard time. There are no default rules, so if you want to define a zone that switches seasonally between standard and daylight time, you must specify the rules.

new TimeZone('UTC')

'Z' and 'GMT' are equivalent. This creates a TimeZone object representing UTC (Universal Time Coordinated), also known as Zulu (Z) time in military and aviation jargon. This is the worldwide standard reference point for timekeeping; all modern time zones are defined in terms of their offset (clock time difference) from UTC. GMT isn't technically the same as UTC, but the two terms are commonly used interchangeably, which is why both are accepted here. UTC isn't subject to daylight time; it's on "standard time" year round.

new TimeZone('UTC+offset')

'Z+offset' and 'GMT+offset' are equivlaent. This creates a TimeZone object representing a zone at a fixed offset (time difference) from UTC. offset is a time difference in hours, hours and minutes, or hours, minutes, and seconds: 'UTC-8' is eight hours west of UTC; 'UTC+0130' is an hour and half east of UTC; 'UTC+01:00' is an hour east. The offset is the amount of time you add to UTC to get the local time, which means that negative numbers are west of UTC: Pacific Standard Time is UTC-8.

Be careful about the '+' or '-' sign when importing data from other computer systems, since some systems use the opposite sign convention. Unix in particular uses positive values for zones west of GMT.

A TimeZone object created this way uses the same fixed UTC offset for all dates and times. It doesn't observe daylight savings time and doesn't have any historical data on zone realignments, because it doesn't represent a timezone per se, even if it happens to align (in some or all of the year) with a defined regional zone. For example, 'UTC-8' is distinct from the US Pacific Time zone, even though it happens to be at the same UTC offset as that zone's standard (winter) time; the difference is that the US Pacific Time zone implies a history of daylight savings and other changes, while 'UTC-8' is simply 8 hours earlier than UTC for all dates and times.

new TimeZone(offsetSecs)

Creates a TimeZone object at the fixed UTC offset. offsetSecs is an integer giving the time zone offset in seconds; positive values are east of UTC and negative values are west (e.g., US Pacific Daylight Time is at -25200 seconds, which is -7 hours).

This type of TimeZone object is equivalent to the 'UTC+offset' constructor above for the corresponding offset. For example, new TimeZone(-25200) yields the same type of time zone object as new TimeZone('UTC-7').

Methods

getNames()

Returns a list of strings giving the names by which the timezone is known. For a timezone based on a zoneinfo location, this returns a list of all of the aliases by which the zone is known; the first entry is the primary entry in the database for the zone, and the others are aliases (called "links" in the zoneinfo database). For a zone based on an abbreviation, the list has only one entry, with the abbreviation as the name. For a zone based on a UTC offset, the list has only one entry, with a name of the form 'UTC+hh:mm:ss' (but the seconds and minutes are dropped if they're zero).

getHistory(date?)

Gets the enumerated history of clock setting changes in this timezone, or the single history item that applies to the given date.

If date is supplied, it's a Date object specifying the date of interest. The method finds the appropriate history item and returns it; the return value is a list containing [date, offset, save, abbr]:

getLocation()

Returns a description of the zone location, as a list consisting of [country, latitude, longitude, desc]. country is a string with the two-letter ISO 3166 country code for the zone's primary city, latitude is a string giving the city's latitude (in '+ddmm' or '+ddmmss' format - degrees, minutes, and seconds; '+' for northern latitudes and '-' for southern), longitude is a string giving the longitude (in '+dddmm' or '+dddmmss' format), and desc is a string with comment text describing the zone (or nil if there's no descriptive text). This information comes from the zoneinfo database.

getRules()

Gets the ongoing rules that are in effect after the last enumerated history item (see getHistory()). This returns a list of the rules for future changes to the zone; each rule fires once annually, and encodes the day of the year when the rule fires, the time on that day that it fires, and the new clock settings in effect after the rule fires.

Virtually all zones that use ongoing rules have exactly two: one for the annual change to daylight savings time in the spring, and one for the return to standard time in the fall. Each rule's firing date is specified in an abstract format designed to handle the variety of regional daylight savings schemes: "last Sunday in March", "second Sunday in November", "January 15", etc. Zones that don't observe daylight savings time generally have no ongoing rules, since they presumably plan to remain on the same standard time setting indefinitely.

Each rule in the return list is described by a sublist with the following elements: