如果设备日期在 Swift 中发生变化,则计时器递减时间会发生变化

Timer decrement time changing if device date changes in Swift

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

 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 日,它会显示更多的天数和时间来解锁。

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

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

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

我找到了解决办法。 我刚刚卸载了 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)"
    }

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