matt
matt

Reputation: 536019

TimeZone name / abbreviation from offset

I'm starting with a GMT offset in seconds, and I want the name of the corresponding time zone. I'm saying:

let offset = -28800
let tz = TimeZone(secondsFromGMT: offset)
let tzname = tz?.localizedName(for: .standard, locale: Locale.current)

I've tried many ways of getting tzname but all I ever get is GMT-05:00. That's not what I want. I'm hoping for something like "Eastern Standard Time" or "EST". Is there a way to get it?

I do not want to pass through some sort of reverse geocoding. I expect the system simply to hand me the answer. Other responses to this sort of question on Stack Overflow seem to indicate that that's what it ought to do, but it isn't doing it.

Upvotes: 4

Views: 789

Answers (1)

Rob
Rob

Reputation: 438437

You cannot use the seconds offset from GMT, alone, to uniquely determine the timezone abbreviation. There is not a one-to-one correspondence between offsets and timezones.

This probably isn't going to be satisfying, but you can get a list of matching timezones by iterating through the knownTimeZoneIdentifiers and find a list of matching time zones:

let abbreviationsAndIdentifiers = TimeZone.knownTimeZoneIdentifiers
    .compactMap { TimeZone(identifier: $0) }
    .filter { $0.secondsFromGMT() == -28800 }

From there, you can use map to grab either abbreviation(for:), identifier or localizedName(for:locale:) to get PST, America/Los_Angeles or Pacific Standard Time for -28800, respectively. Obviously, the above may return a variety of different matches depending on the offset and time of year.


A few caveats for future readers:

  • Timezone abbreviations are not unique. See https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations and you’ll see the same three letter abbreviation mapping to completely different time zones. E.g. CST can mean “Central Standard Time” (in North America), “Cuba Standard Time” or “China Standard Time”.

  • Be wary about the fact that an offset from GMT of -28800 will result in different timezones depending upon the time of the year. E.g. -28800 will return one set of timezone matches in January and another set in July because of daylight savings. Consider using secondsFromGMT(for:), specifying the date, instead, to remove any ambiguity.

Upvotes: 4

Related Questions