如何在 Swift 中使用 pod TimeZoneLocate 获得夏令时
How to get daylight saving time with using pod TimeZoneLocate in Swift
我正在将本地时区转换为字符串以在屏幕上显示。为此,我使用 TimeZoneLocate 库。问题:由于未实施夏令时,我得到的日期结果比实际时间少一小时。
我从 sunrise-sunset.org 获取 JSON,并使用以下行:sunrise = "3:22:31 AM";日落 =“下午 5:23:25”。
我考虑过使用函数 isDaylightSavingTime()
和 if
语句,但我不知道在哪里添加这一小时。
这是魔法发生的地方:
func UTCToLocal(incomingFormat: String, outgoingFormat: String, location: CLLocation?) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = incomingFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: self)
let timeZone = location?.timeZone ?? TimeZone.current
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = outgoingFormat
return dateFormatter.string(from: dt ?? Date())
}
我使用来自 CLLocation 的本地 "location",TimeZone.current 由 TimeZoneLocate 库提供。
这是我在代码中使用它的方式:
func parce(json: Data, location: CLLocation) {
let decoder = JSONDecoder()
if let sunriseData = try? decoder.decode(Results.self, from: json) {
self.sunriseLbl.text = sunriseData.results?.sunrise.UTCToLocal(incomingFormat: "h:mm:ss a",
outgoingFormat: "HH:mm",
location: location)
sunriseLbl 正在默认打印来自 JSON 的当前位置的日出数据,以及 GooglePlaces 的任何地点的日出数据。但是,在两者中,我都得到了错误的日期。
此外,这是我在 GitHub 上的项目的 link,如果它可以帮助你帮助我:https://github.com/ArtemBurdak/Sunrise-Sunset。
提前致谢
我注意到一件有趣的事:TimeZone.current
是返回正确的时区,但location?.timeZone
不是 返回正确的时区。如果有实现 TimeZone.current 的方法,即应用程序将始终使用用户的当前位置,那么我建议使用它。但是,如果用户可以输入自定义位置,那么您需要为 location?.timeZone
.
返回的明显不正确的时区找到解决方法
我的解决方法如下。请注意,我们通过更改 .secondsFromGMT()
属性 手动调整了我们想要的时区位置。这就是我调整您的代码的方式,它为我的个人位置返回了正确的时区。
extension String {
func UTCToLocal(incomingFormat: String, outgoingFormat: String, location: CLLocation?) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = incomingFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: self)
var timeZone = location?.timeZone ?? TimeZone.current
if timeZone.isDaylightSavingTime() {
timeZone = TimeZone(secondsFromGMT: timeZone.secondsFromGMT() - 7200)!
}
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = outgoingFormat
let output = dateFormatter.string(from: dt ?? Date())
return output
}
}
注意:
时区非常复杂,并且随着时间的推移和一年中的当前时间而变化。仅仅因为此解决方法适用于我当天的当前位置,并不意味着此解决方法始终有效。 但是,您可以根据需要查看返回的timeZone.isDaylightSavingTime()
值以及当前位置,通过timeZone = TimeZone(secondsFromGMT: timeZone.secondsFromGMT() - x
创建新的时区。这是您可以实现
的方式
"I thought about using function isDaylightSavingTime() with if statement, but I can't figure out where to add this one hour."
你的想法。
编辑:
作为记录,我使用的时区是 CST,即芝加哥时间。我写这段代码的日期是 2019 年 4 月 19 日。
我正在将本地时区转换为字符串以在屏幕上显示。为此,我使用 TimeZoneLocate 库。问题:由于未实施夏令时,我得到的日期结果比实际时间少一小时。
我从 sunrise-sunset.org 获取 JSON,并使用以下行:sunrise = "3:22:31 AM";日落 =“下午 5:23:25”。
我考虑过使用函数 isDaylightSavingTime()
和 if
语句,但我不知道在哪里添加这一小时。
这是魔法发生的地方:
func UTCToLocal(incomingFormat: String, outgoingFormat: String, location: CLLocation?) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = incomingFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: self)
let timeZone = location?.timeZone ?? TimeZone.current
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = outgoingFormat
return dateFormatter.string(from: dt ?? Date())
}
我使用来自 CLLocation 的本地 "location",TimeZone.current 由 TimeZoneLocate 库提供。
这是我在代码中使用它的方式:
func parce(json: Data, location: CLLocation) {
let decoder = JSONDecoder()
if let sunriseData = try? decoder.decode(Results.self, from: json) {
self.sunriseLbl.text = sunriseData.results?.sunrise.UTCToLocal(incomingFormat: "h:mm:ss a",
outgoingFormat: "HH:mm",
location: location)
sunriseLbl 正在默认打印来自 JSON 的当前位置的日出数据,以及 GooglePlaces 的任何地点的日出数据。但是,在两者中,我都得到了错误的日期。
此外,这是我在 GitHub 上的项目的 link,如果它可以帮助你帮助我:https://github.com/ArtemBurdak/Sunrise-Sunset。
提前致谢
我注意到一件有趣的事:TimeZone.current
是返回正确的时区,但location?.timeZone
不是 返回正确的时区。如果有实现 TimeZone.current 的方法,即应用程序将始终使用用户的当前位置,那么我建议使用它。但是,如果用户可以输入自定义位置,那么您需要为 location?.timeZone
.
我的解决方法如下。请注意,我们通过更改 .secondsFromGMT()
属性 手动调整了我们想要的时区位置。这就是我调整您的代码的方式,它为我的个人位置返回了正确的时区。
extension String {
func UTCToLocal(incomingFormat: String, outgoingFormat: String, location: CLLocation?) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = incomingFormat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: self)
var timeZone = location?.timeZone ?? TimeZone.current
if timeZone.isDaylightSavingTime() {
timeZone = TimeZone(secondsFromGMT: timeZone.secondsFromGMT() - 7200)!
}
dateFormatter.timeZone = timeZone
dateFormatter.dateFormat = outgoingFormat
let output = dateFormatter.string(from: dt ?? Date())
return output
}
}
注意:
时区非常复杂,并且随着时间的推移和一年中的当前时间而变化。仅仅因为此解决方法适用于我当天的当前位置,并不意味着此解决方法始终有效。 但是,您可以根据需要查看返回的timeZone.isDaylightSavingTime()
值以及当前位置,通过timeZone = TimeZone(secondsFromGMT: timeZone.secondsFromGMT() - x
创建新的时区。这是您可以实现
"I thought about using function isDaylightSavingTime() with if statement, but I can't figure out where to add this one hour."
你的想法。
编辑: 作为记录,我使用的时区是 CST,即芝加哥时间。我写这段代码的日期是 2019 年 4 月 19 日。