我正在尝试获取用户点击的全球地图上的位置的时区。我只有这些点的坐标。我可以创建 CLLocation 和 reverseGeocodeLocation 来获取地标和时区,但这仅在用户连接到互联网时才有效。
由于时区边界是固定的,想知道是否有办法在离线时使用 Swift 库获取某个位置的时区?我不是在寻找第三方库来实现这一目标。
在线查询代码为:
let clLocation = CLLocation(latitude: location.latitude, longitude: location.longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(clLocation) { placemarks, error in
if let error = error {
print(error.localizedDescription)
} else {
if let placemarks = placemarks {
if let timeZone = placemarks.first!.timeZone {
self.timeZone = timeZone
}
}
}
}
基本上有两种选择:
最简单的方法是从位置获取时区。当使用
timestamp
调用时,CLLocation
的 description(with:
属性会显示当前时区标识符。正则表达式可以提取时区字符串
import CoreLocation
let currentLocation = CLLocation(latitude: 47.36667, longitude: 8.55) // Location of Zurich
let date = currentLocation.timestamp.description(with: Locale(identifier: "en_US_POSIX"))
let timeRange = date.firstRange(of: /(A|P)M\s/)
let timeZone = date[timeRange!.upperBound...]
print(String(timeZone)) // Central European Summer Time
否则,您需要一个像这个这样的查找表,一个文本格式的时区及其位置列表(链接列表中的 CSV)
创建一个辅助结构
struct TimeZoneData {
let name: String
let location: CLLocation
}
将 CSV 列表映射到结构体的实例并计算距当前位置的最近距离。
timeZoneCSV
代表 CSV 文本
import CoreLocation
let currentLocation = CLLocation(latitude: 47.36667, longitude: 8.55) // Location of Zurich
let nearestTimeZone = timeZoneCSV.components(separatedBy: .newlines)
.map { line in
let fields = line.components(separatedBy: ";")
return TimeZoneData(name: fields[0], location: CLLocation(latitude: Double(fields[1])!, longitude: Double(fields[2])!))
}
.sorted(by: {$0.location.distance(from: currentLocation) < $1.location.distance(from: currentLocation)}).first!
print(nearestTimeZone) // "Europe/Zurich
请注意,第一个选项显示时区标识符的长版本,第二个选项显示时区名称。