【发布时间】: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