TimeZone: get the abbreviation instead of the GMT offset

114 Views Asked by At

I need to get the abbreviation of the timezone.

For example, Moscow, Russia has the abbreviation MSK. Central European Time has the abbreviation of CET, Eastern European Summer Time has EEST, etc.

When I open the macOS settings, I can see the abbreviation clearly:

 macos settings screenshot

However, when I try to get the abbreviation in code, I get only the GMT offset:

import UIKit
let date = Date()
let zone = TimeZone(abbreviation: "EEST")
print(zone?.abbreviation(for: Date()))

Optional("GMT+3")

On the other hand, when I try to use the US time, I get the correct abbreviation:

import UIKit
let date = Date()
let zone = TimeZone(abbreviation: "EDT")
print(zone?.abbreviation(for: Date()))

Optional("EDT")

How can I always enforce TimeZone to give the abbreviation instead of the GMT offset? Are there any other way to always get the abbreviation, regardless of the locale, or other system settings?

My goal is to get the same string as in the macOS settings.

1

There are 1 best solutions below

0
Cuong Nguyen On

I've play with snippet code. Hope that helps you solve your problem.

import Foundation
import UIKit
import CoreLocation

public struct LocalTime {
    var timeZone: TimeZone?
    var dateTime: String
    init(timeZone: TimeZone, dateTime: String) {
        self.timeZone = timeZone
        self.dateTime = dateTime
    }
}

class ViewController: UIViewController {
    var timeZone: TimeZone?
    var localTime: LocalTime?
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.getLocalTimeZone(lat: 47.6062, lon: -122.3321, dateTime: "2017-06-10T00:30:00Z")
    }

    override func viewDidAppear(_ animated: Bool) {

    }

    func convertToLocalDateFromUTCDate(dateStr: String) -> String {
        let utcDateFormatter = DateFormatter()
        utcDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
        let sourceDate = utcDateFormatter.date(from: dateStr)
        let localDateFormatter = DateFormatter()
        localDateFormatter.timeZone = self.timeZone
        localDateFormatter.dateFormat = "dd-MM-yyyy HH:mm:'00'"
        guard let date = sourceDate else { return "" }
        let localTime = localDateFormatter.string(from: date)
        return localTime
    }

    func getLocalTimeZone(lat: Double, lon: Double, dateTime: String) {
        let location = CLLocation(latitude: lat, longitude: lon)
        let geoCoder = CLGeocoder()
        var dateTimeString: String?
        geoCoder.reverseGeocodeLocation(location) { [weak self] (placemarks, err) in
            if let placemark = placemarks?[0] {
                guard let self = self else { return }
                dateTimeString = self.convertToLocalDateFromUTCDate(dateStr: dateTime)
                guard let timeZone = placemark.timeZone, let dateTimeString = dateTimeString else { return }
                self.localTime = LocalTime(timeZone: timeZone, dateTime: dateTimeString)
                debugPrint("\(self.localTime?.timeZone?.abbreviation())")
                debugPrint("\(self.localTime?.dateTime)")
            }
        }
    }

}

Output:

"Optional(\"PDT\")"
"Optional(\"10-06-2017 07:30:00\")"