Since network calls are expensive,
you shouldn't make the same network call every time you need to get corrected datetime.
When getting time from some server, store the time difference between local and the server somewhere and use it to get corrected date.
example
private var timeGap: TimeInterval = 0
private var referenceDate = Date() {
didSet { timeGap = Date().distance(to: referenceDate) }
}
var correctedDate: Date {
let possibleDate = Date()
let ignorableNetworkDelay: TimeInterval = 2
guard abs(timeGap) > ignorableNetworkDelay else { return possibleDate }
return possibleDate.advanced(by: timeGap)
}
func setReferenceDate() {
let url = URL(string: "https://www.google.com")
URLSession.shared.dataTask(with: url!) { _, response, _ in
let httpResponse = response as? HTTPURLResponse
if let stringDate = httpResponse?.allHeaderFields["Date"] as? String {
let formatter = DateFormatter()
formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss z"
formatter.timeZone = TimeZone.current
serverDate = formatter.date(from: stringDate) ?? Date()
} else {
print("getting reference date from web failed")
referenceDate = Date()
}
}.resume()
}
This way, I can refer to correctedDate
any time without worrying about the cost,
and call setReferenceDate()
only when I need to correct datetime.
(for instance, when the app goes into background)