iosswiftswift4swift4.2

How to get current date from current timezone from a time server in Swift?


I am working on application where i want to get current date as per the users current timezone. even after user changes date from their device setting menu.

To get the current timezone i have used

let timeZone = TimeZone.current
print(timeZone)

for example here i got 'Asia/Kolkata' and current date is 28-july, now if user changes date (Setting->Date&Time-> off set automatically) to 29-july at that time i got output like 'Asia/Kolkata' date 29-july, but actual date is 28-july. so how can i get current date of this (Asia/Kolkata) timezone.

Note: I want to use this because i need current date of particular timezone if user tries to change date from setting then after i need to get exact date from that timezone.


Solution

  • If you need to make sure the date is a valid date you can use a timeserver to return the date based on the device IP, of course this will require an internet connection.

    You can create a asynchronous method to return the current date regardless of the user timezone and its timezone as well:


    struct Root: Codable {
        let unixtime: Date
        let timezone: String
    }
    

    extension URL {
        static let timeIP = URL(string: "http://worldtimeapi.org/api/ip")!
        static func asyncTime(completion: @escaping ((Date?, TimeZone?, Error?)-> Void)) {
            URLSession.shared.dataTask(with: .timeIP) { data, response, error in
                guard let data = data else {
                    completion(nil, nil, error)
                    return
                }
                do {
                    let decoder = JSONDecoder()
                    decoder.dateDecodingStrategy = .secondsSince1970
                    let root = try decoder.decode(Root.self, from: data)
                    completion(root.unixtime, TimeZone(identifier: root.timezone), nil)
                } catch {
                    completion(nil, nil, error)
                }
            }.resume()
        }
    }
    

    Usage:

    URL.asyncTime { date, timezone, error in
        guard let date = date, let timezone = timezone else {
            print("Error:", error ?? "")
            return
        }
        print("Date:", date.description(with: .current))  // "Date: Tuesday, July 28, 2020 at 4:27:36 AM Brasilia Standard Time\n"
        print("Timezone:", timezone)   // "Timezone: America/Sao_Paulo (current)\n"
    }