Localize Timezone display names in Swift

Jianyuan Chen
4 Minute Swift
Published in
3 min readApr 30, 2021

The time zone localization tips missing from Apple’s official documentation

I came across a requirement from the product team earlier today where they want to display a UTC date in the format: April 30th, 2021 (Vancouver Time), and it should be localized to the device’s active locale.

After some research, it is clear that the Foundation framework already comes equipped with the common operations you would do with time zones.

According to Apple’s documentation, you would use a TimeZone to :

TimeZone defines the behavior of a time zone. Time zone values represent geopolitical regions. Consequently, these values have names for these regions. Time zone values also represent a temporal offset, either plus or minus, from Greenwich Mean Time (GMT) and an abbreviation (such as PST for Pacific Standard Time).

TimeZone construction

A TimeZone struct can be constructed in two ways:

  1. By time zone identifier, via TimeZone(identifier: _) if your city identifier (usually in the format: "America/Los_Angeles") happens to match one of the options Apple stored in the framework.
  2. By time zone abbreviation, via TimeZone(abbreviation: _). For example “PST” stands for “Pacific Standard Time”, and its associated city, according to Apple’s data is America/Los_Angeles. This can be thought of as the most iconic city associated with the time zone abbreviation.

The complete list of time zone identifiers can be accessed through the static variable TimeZone.knownTimeZoneIdentifiers. (An excerpt is printed below. The complete list can be found here.)

[
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"America/Argentina/Buenos_Aires",
"America/Argentina/Catamarca",
"Antarctica/Troll",
"Antarctica/Vostok",
"Arctic/Longyearbyen",
"Asia/Aden",
"Asia/Almaty",
"Asia/Amman",
"Atlantic/St_Helena",
"Atlantic/Stanley",
"Australia/Adelaide",
"Australia/Brisbane",
"Australia/Broken_Hill",
"Europe/Amsterdam",
"Europe/Andorra",
"Europe/Astrakhan",
"GMT",
"Indian/Antananarivo",
"Indian/Chagos",
"Indian/Christmas",
"Pacific/Apia",
"Pacific/Auckland",
"Pacific/Bougainville",
...
]

The complete list of time zone abbreviation to identifier dictionary can be accessed through TimeZone.abbreviationDictionary. (Complete list can be found here)

[   
"WAT": "Africa/Lagos",
"EAT": "Africa/Addis_Ababa",
"MDT": "America/Denver",
...
]

TimeZone conversion

Once you have constructed the time zone struct, you can get its localized display name with the following method:

timezone.lolicazedName(for: NSTimeZone.NameStyle, locale: Locale?)

NSTimeZone.NameStyle is an enum consist of 6 options:

  1. .standard: Gives the name of the time zone which usually contains the word “standard”.
  2. .shortStandard: Gives the standard time in the format of time offset from GMT +0.
  3. .dayLightSaving: Gives the daylight saving time label for the specific time zone.
  4. .shortDayLightSaving
  5. .generic
  6. .shortGeneric: Gives the localized name down to the city. For example, if you use the time zone “America/Vancouver”, the converted name would be “Vancouver Time”. However some countries like China have unified time zone across the country, so even though you specify “Asia/Shanghai”, the result will be “China Mainland Time” instead of “Shanghai Time”

Locale determines which language the returned time zone label would be translated into. For example, "zh_Hans_CN" gives Simplified Chinese, "en_UK" gives the name in British English convention. In most cases, you would want to show the name based on the current device’s active locale, which can be accessed through Locale.current.

Below are the results of printing the localized name for each name style and locale combination:

========For timezone: "Asia/Shanghai" and locale: "en_UK"
.standard: China Standard Time
.shortStandard: GMT+8
.dayLightSaving: China Daylight Time
.shortDaylightSaving: GMT+8
.generic: China Standard Time
.shortGeneric: China mainland Time
========For timezone: "Asia/Shanghai" and locale: "zh_Hans_CN"
.standard: 中国标准时间
.shortStandard: GMT+8
.dayLightSaving: 中国夏令时间
.shortDaylightSaving: GMT+8
.generic: 中国标准时间
.shortGeneric: 中国大陆时间
========For timezone: "America/Vancouver" and locale: "en_UK"
.standard: Pacific Standard Time
.shortStandard: GMT-8
.dayLightSaving: Pacific Daylight Time
.shortDaylightSaving: GMT-7
.generic: Pacific Time
.shortGeneric: Vancouver Time
========For timezone: "America/Vancouver" and locale: "zh_Hans_CN"
.standard: 北美太平洋标准时间
.shortStandard: GMT-8
.dayLightSaving: 北美太平洋夏令时间
.shortDaylightSaving: GMT-7
.generic: 北美太平洋时间
.shortGeneric: 温哥华时间

P.S.:

This github gist is a list of locale identifiers for quick reference, which could be very handy during testing.

--

--