【问题标题】:Timer decrement time changing if device date changes in Swift如果设备日期在 Swift 中更改,则计时器递减时间会更改
【发布时间】:2021-09-30 07:54:45
【问题描述】:

我从服务器得到两个日期。当前时间和解锁时间。

 Unlock date: 2021-07-23 05:55:44 +0000 
 Current date: 2021-07-23 05:54:44 +0000

所以,我必须从解锁日期减去当前日期和剩余时间,我必须运行计时器才能解锁。

let client = TrueTimeClient.sharedInstance

 override func viewDidLoad() {
        super.viewDidLoad()

 let when = DispatchTime.now() + 0.1
            DispatchQueue.main.asyncAfter(deadline: when) {
                
                self.countDownTimer = .scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
                    self?.countDownTime()
                }
            }

}

    @objc func countDownTime() {
        
        let ntpTime = client.referenceTime?.now()
        let unlockDuration = self.getUnlockCountDownTime(currentTime: unlocksTime ?? "" , unlockTime: unlocksTime ?? "", ntpDate: ntpTime ?? Date())
        unlockHrsLabel.text = "\(unlockDuration)"
        if unlockDuration == "0d :0h : 0: 0" {
        self.stopTimer()
          //call some api

   }
}

    func getUnlockCountDownTime(currentTime: String, unlockTime: String, ntpDate: Date) -> String {
        
        let dateFormatter = DateFormatter()
        let loc = Locale(identifier: "en_US_POSIX")
        dateFormatter.locale = loc
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
//        dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
        let unlockDate = dateFormatter.date(from: "\(unlockTime)") ?? Date()
        print("unlockDate \(unlockDate)")
        print("ntpDate \(ntpDate)")
        let currentDate = dateFormatter.date(from: "\(currentTime)") ??  Date()
        print("currentDate \(currentDate)")

        let calendar = Calendar.current
        let diffDateComponents = calendar.dateComponents([.day, .hour, .minute, .second], from: unlockDate, to: ntpDate)
        let countdown = "\(String(describing:diffDateComponents.day!))d :\(String(describing: diffDateComponents.hour!))h : \(String(describing: diffDateComponents.minute!)): \(String(describing: diffDateComponents.second!))"
    //    print(countdown)
        return countdown
    }

 func stopTimer(){
        guard self.countDownTimer != nil else {
            fatalError("No timer active, start the timer before you stop it.")
        }
        self.countDownTimer?.invalidate()
    }

这里,我使用 pod 'TrueTime' 来获取 ntp 时间,但是如果我们更改设备时间,计时器持续时间会自动增加。

假设,我的剩余时间为 1:50 秒,如果我将日期更改为 2021 年 6 月 20 日,它会显示更多天数和小时数来解锁。

无论时间变化和时区如何,我都必须始终显示解锁计时器的持续时间。

它应该如上图所示。但是,如果我更改日期,它会出现如下错误的屏幕

如何解决这个问题?有什么建议吗?

【问题讨论】:

  • 将解锁逻辑与 UI 逻辑分开,将一个计时器设置为在总持续时间后触发一次,然后使用不同的计时器(或其他解决方案)倒计时并更新 UI
  • 我将首先消除所有Date() 的使用;你不能相信本地设备时间。如果您无法解析传入的日期会引发错误或其他问题,请不要回退到Date()。一旦您的代码独立于设备时间,设备上发生的事情就无关紧要了。另外,为什么要反复将字符串转换为Date。当然,你可以这样做一次。然后你只需要跟踪经过的时间。
  • 感谢@JoakimDanielson 提出的宝贵建议
  • 感谢@Paulw11 提出的宝贵建议

标签: ios swift iphone nsdate utc


【解决方案1】:

我找到了解决方案。 我刚刚卸载了 pod 'TrueTime' 并使用 timeinterval 减去当前时间以解锁时间然后我运行了剩余秒数的计时器。 然后我运行定时器并减少余数。

  @objc func countDownTime() {
            
            self.remainingTime -= 1
            seunlockHrsLabel.text = "\(self.convertIntegerToFormat(remainingTime: self.remainingTime))"
            if remainingTime == 0 {
                self.stopTimer()
      }
  }
    func convertIntegerToFormat(remainingTime: Int) -> String {
            
            let days = remainingTime / (24 * 3600)
            let hours = remainingTime / 3600
            let seconds = remainingTime % 60
            let minutes = (remainingTime / 60) % 60
            
            
            return "\(days): \(hours): \(minutes): \(seconds)"
    }

现在,无论设备时间和时区如何,它都可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多