如何从 Swift 中的时间服务器获取当前时区的当前日期?
How to get current date from current timezone from a time server in Swift?
我正在处理我想根据用户当前时区获取当前日期的应用程序。即使在用户从他们的设备设置菜单更改日期之后。
获取我使用的当前时区
let timeZone = TimeZone.current
print(timeZone)
例如,我得到 'Asia/Kolkata',当前日期是 7 月 28 日,现在如果用户将日期(设置-> 日期和时间-> 自动关闭设置)更改为 7 月 29 日,我得到的输出如下'Asia/Kolkata' 日期为 7 月 29 日,但实际日期为 7 月 28 日。那么我怎样才能得到这个(Asia/Kolkata)时区的当前日期。
注意:我想使用它,因为如果用户试图从设置中更改日期,那么我需要特定时区的当前日期,然后我需要从该时区获取确切日期。
这是一个简单的解决方案:
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: Date()))
let date = Date(timeInterval: seconds, since: Date())
print(date)
您也可以简单地使用 Date()
,但是在使用它来显示它时使用 DateFormatter
。这是一个例子:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let formattedDate = dateFormatter.string(from: Date())
print(formattedDate)
如果你想要用户的当前日期,你可以简单地实现let date = Date()
。它将 return 用户设备上使用的日期。
例如,这将为我显示
let date = Date() // Jul 28, 2020 at 8:22 AM
var timezone = TimeZone.current // Europe/Berlin (current)
如果您需要确保日期是有效日期,您可以使用时间服务器 return 基于设备 IP 的日期,当然这需要互联网连接。
您可以创建一个异步方法 return 当前日期,而不考虑用户时区及其时区:
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()
}
}
用法:
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"
}
我正在处理我想根据用户当前时区获取当前日期的应用程序。即使在用户从他们的设备设置菜单更改日期之后。
获取我使用的当前时区
let timeZone = TimeZone.current
print(timeZone)
例如,我得到 'Asia/Kolkata',当前日期是 7 月 28 日,现在如果用户将日期(设置-> 日期和时间-> 自动关闭设置)更改为 7 月 29 日,我得到的输出如下'Asia/Kolkata' 日期为 7 月 29 日,但实际日期为 7 月 28 日。那么我怎样才能得到这个(Asia/Kolkata)时区的当前日期。
注意:我想使用它,因为如果用户试图从设置中更改日期,那么我需要特定时区的当前日期,然后我需要从该时区获取确切日期。
这是一个简单的解决方案:
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: Date()))
let date = Date(timeInterval: seconds, since: Date())
print(date)
您也可以简单地使用 Date()
,但是在使用它来显示它时使用 DateFormatter
。这是一个例子:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let formattedDate = dateFormatter.string(from: Date())
print(formattedDate)
如果你想要用户的当前日期,你可以简单地实现let date = Date()
。它将 return 用户设备上使用的日期。
例如,这将为我显示
let date = Date() // Jul 28, 2020 at 8:22 AM
var timezone = TimeZone.current // Europe/Berlin (current)
如果您需要确保日期是有效日期,您可以使用时间服务器 return 基于设备 IP 的日期,当然这需要互联网连接。
您可以创建一个异步方法 return 当前日期,而不考虑用户时区及其时区:
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()
}
}
用法:
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"
}