我有一个 ISO-8601 日期字符串,如下所示:"2017-02-07T00:00:00-08:00"
.
如何从此日期提取时区对象?
不幸的是,DateFormatter
没有帮助,因为您不需要Date
,也不提供有关解析日期字符串的任何时区信息的任何信息。而且TimeZone
没有任何可以解析时区偏移量字符串的初始值设定项。
所以你将不得不自己做这项工作。由于您有一个固定格式的日期字符串,因此您知道时区偏移量始终是字符串的最后 6 个字符。其中最后 2 分钟数,前 3 小时数(包括标志(。
从日期字符串中提取这两个子字符串(小时和分钟(。将它们都转换为Int
.然后做一些简单的数学运算来计算以秒为单位的偏移量(小时 * 3600 + 分钟 * 60(。
获得该偏移量(以秒为单位(后,您可以使用 init(secondsFromGMT:)
初始值设定项创建 TimeZone
实例。
使用 rmaddys 提出的解决方案,我为 TimeZone
编写了一个扩展,它应该可以完成这项工作。
extension TimeZone {
init?(iso8601String: String) {
let timeZoneString = String(iso8601String.suffix(6))
let sign = String(timeZoneString.prefix(1))
guard sign == "+" || sign == "-" else {
return nil
}
let fullTimeString = timeZoneString.filter("0123456789".contains)
guard fullTimeString.count == 4 else {
return nil
}
guard let hours = Int(sign+fullTimeString.prefix(2)), let minutes = Int(sign+fullTimeString.suffix(2)) else {
return nil
}
let secondsFromGMT = hours * 3600 + minutes * 60
self.init(secondsFromGMT: secondsFromGMT)
}
}
您可以创建一个仅返回时区的日期格式化程序,如下所示。将缩写更改为您要查找的任何时区。
let timeZoneOnlyDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.timeZone = TimeZone(abbreviation: "UTC")
formatter.dateStyle = .none
formatter.timeStyle = .none
return formatter
}()
并使用这些函数将其转换为字符串或将字符串转换为日期。
func formatDateIntoString(date: Date, dateFormatter: DateFormatter) -> String {
return dateFormatter.string(from: date)
}
func formatStringIntoDate(string: String, dateFormatter: DateFormatter) -> Date! {
return dateFormatter.date(from: string)
}