Search code examples
iosswiftiphonensdateutc

Timer decrement time changing if device date changes in Swift


I am getting two dates from server. Current time and Unlock time.

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

So, I have to subtract from unlock date to current date and Remainder time, I have to run timer to unlock.

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()
    }

Here, I have used pod 'TrueTime' to fetch ntp time, but if we change device time, the timer duration increasing automatically.

Suppose, i am getting remainder time 1:50 seconds, If I change date to june 20, 2021, Its showing more days and hours to unlock.

I have to show always unlock timer duration same irrespective time changes and time zones.

enter image description here

It should come as above screenshot. But, if I change date, it is coming as below screen which is wrong

enter image description here

How to fix this? Any suggestions?


Solution

  • I have found solution. I just uninstalled pod 'TrueTime' and subtract current time to unlock time using timeinterval Then I have run timer with remainder seconds. Then I run timer with decrement of remainder.

      @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)"
        }
    

    Now, It is working irrespective of device time and time zones.