3

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.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • https://stackoverflow.com/a/27255138/2303865 – Leo Dabus Feb 16 '20 at 03:24
  • @LeoDabus Yes that's the main answer I'm talking about. It seems to imply that this should work as I expect. – matt Feb 16 '20 at 04:02
  • I have implemented something similar of what Rob suggested to select the current timezone from the list of known timezones. You can check it here https://testflight.apple.com/join/19gnJJSh you will notice that the abbreviation it is only available to the US timezones – Leo Dabus Feb 16 '20 at 12:03

1 Answers1

3

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.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • So basically I'd have to make for myself the table that I expect the system to contain already? And how do we explain all the answers that claim I should be getting names like Eastern Standard Time already? Is it because I started with an offset rather than an abbreviation? I can only get an abbreviation out if I put an abbreviation in to start with? – matt Feb 16 '20 at 01:01
  • Yeah, with the offset alone, it has no way of knowing which one to use. Re the other answers, I can't say without seeing the question. Maybe they're just wrong. Maybe they didn't use `TimeZone(secondsFromGMT:)`. Maybe there was some old behavior that they were relying upon. But given that there is not a one-to-one correspondence between seconds offset from GMT and time zone abbreviations, I don't see how those other answers could have worked on the basis of what you've described. – Rob Feb 16 '20 at 01:08
  • “I can only get an abbreviation out if I put an abbreviation in to start with?” ... Yep, or with identifier (which is safer given that abbreviations are not unique). – Rob Feb 16 '20 at 01:22
  • Well yes, there is sort of a correspondence, as your solution illustrates. The offset is how the API (openweathermap) tells me the time zone. (I also have latitude and longitude but TimeZone won’t tell me the name from that either.) – matt Feb 16 '20 at 02:01