如果设备日期在 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)"
}
现在,无论设备时间和时区如何,它都可以正常工作。
我从服务器得到两个日期。当前时间和解锁时间。
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)"
}
现在,无论设备时间和时区如何,它都可以正常工作。