【问题标题】:How to get daylight saving time with using pod TimeZoneLocate in Swift如何在 Swift 中使用 pod TimeZoneLocate 获得夏令时
【发布时间】:2019-09-09 21:25:32
【问题描述】:

我正在将本地时区转换为字符串以在屏幕上显示。为此,我使用 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 的本地“位置”,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 上的项目的链接,如果它可以帮助你的话:https://github.com/ArtemBurdak/Sunrise-Sunset

提前致谢

【问题讨论】:

  • 你能举例说明你的传入格式吗?
  • 您需要告诉我们incomingFormatoutgoingFormatlocationdtlocation.timeZoneTimeZone.current 的确切值。
  • 我正在获取 JSON,并使用以下行:sunrise = "3:22:31 AM";日落 =“下午 5 点 23 分 25 秒”。我使用 CLLocation 中的本地位置,TimeZone.current 由 TimeZoneLocate 库提供
  • 你是如何实现这个的?这个函数是作为 String 类型的扩展调用的吗?我试图重新创建它,但“self”不是字符串类型,所以let dt = dateFormatter.date(from: self) 导致错误。
  • 是的,它是字符串的扩展

标签: swift timezone dst


【解决方案1】:

我注意到一件有趣的事情: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 创建新时区。这是你可以实现的方式

“我考虑过将函数 isDaylightSavingTime() 与 if 语句一起使用,但我不知道在哪里添加这一小时。”

你的想法。

编辑: 作为记录,我使用的时区是 CST 或芝加哥时间。我编写此代码的日期是 2019 年 4 月 19 日。

【讨论】:

  • 奇怪的东西。如果我使用 secondsFromGMT: timeZone.secondsFromGMT() - 0,它可以工作!如果我不使用它或输入另一个数字,它会显示错误的时间
  • @ArtemBoordak 很好,但我会从许多不同的时区和许多不同的日期对其进行测试,以确保它不会只是巧合地适用于您当前的时区。您可能需要考虑该国家/地区是否使用某种日光节约时间、一年中的时间等。
猜你喜欢
  • 2016-03-06
  • 2016-03-12
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 2019-09-01
  • 2021-08-28
  • 2013-10-17
  • 2018-03-05
相关资源
最近更新 更多