我试图让我的应用程序在每天到达 9:00 UTC 时间时弹出 viewControllers

I'm trying to have my app pop viewControllers when it reaches 9:00 UTC time every day

我正在尝试让我的应用程序在每天到达 9:00 UTC 时间时弹出 viewControllers。我不希望它使用当地时间,因为它可以在不同地区发生变化,并且可以更改。我想过使用服务器时间,但我在使用该解决方案时遇到了问题。我得到了一个纪元时间戳并将其转换为日期。

let ref = FIRDatabase.database().reference()   
let timestamp = FIRServerValue.timestamp()
  ref.setValue(timestamp)

    ref.observe(.value, with: {
        snap in
        if let t = snap.value as? TimeInterval {
            // Cast the value to an NSTimeInterval
            // and divide by 1000 to get seconds.
            print("this is the time in seconds \(t)")
            let date = Date(timeIntervalSince1970: t)
            print("this is the time \(Date(timeIntervalSince1970: t/1000))")

打印出this is the time 2016-10-10 18:40:21 +0000.

问题是弄清楚如何仅从中获取小时、分钟和秒,以便我可以比较时间日期。

其中一个选项可能是:

  • 在应用程序启动时向服务器请求当前时间。
  • 计算 9:00 UTC 和当前时间之间的差异。
  • 设置一个计时器 (NSTimer),当差异结束时触发。
  • 最后,以您喜欢的任何方式处理回调:弹出屏幕、显示弹出窗口等。

你可以使用这样的东西:

let calendar = Calendar.current
let components = NSDateComponents()
components.hour = 9

let nineOClock = calendar.nextDate(after: Date(), matching: components as DateComponents, matchingPolicy: .strict)

let timer = Timer(fireAt: nineOClock!, interval: 0, target: self, selector: #selector(doSomething), userInfo: nil, repeats: true)
RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)

func doSomething(){
    print("Doing something")
}

一种根据当前时间(自 1970 年以来的秒数)计算到下一个上午 9 点的时间(以秒为单位)的方法。

func untilNineAmSeconds(now: Int) -> Int {

    let todaySeconds = now % 86400
    let hourSeconds = 3600
    let nineAmSeconds = 9 * hourSeconds
    let daySeconds = 24 * hourSeconds

    if todaySeconds < nineAmSeconds {
        return nineAmSeconds - todaySeconds
    } else {
        return (daySeconds - todaySeconds) + nineAmSeconds
    }
}

现在您 (1) 从 Firebase 请求当前时间,(2) 获取上午 9 点之前的时间间隔,以及 (3) 安排计时器。

let ref = FIRDatabase.database().reference()   
let timestamp = FIRServerValue.timestamp()
ref.setValue(timestamp)

ref.observe(.value, with: { snap in
    guard let ts = snap.value as? TimeInterval else {
        return
    }

    let seconds = untilNineAmSeconds(now: Int(ts))

    let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(seconds), repeats: false) { _ in
        // TODO: pop view controllers
    }

    // ...
}

多亏了 Artem 和他的帮助,我才走上了正确的道路。在花了很多时间研究日期转换之后,我弄明白了。最终目标是将这两个值转换为整数,以便我可以在几秒钟内比较它们并在计时器中使用它们来计算剩余时间。

  ref.observe(.value, with: {
        snap in
        if let t = snap.value as? TimeInterval {

     let FinalTimeInterval = self.convertStringToDateToIntStartTime() - self.convertEpochTimeStampToDateToStringToDateToIntEndTime(timeInterval: t)

            if FinalTimeInterval < 0 {
                print("less than zero")
            } else {

            let timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(FinalTimeInterval), repeats: false) { _ in
                // TODO: pop view controllers
                print("i'm so happy this is working")
            }
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)

            }

        }
    })


  func convertEpochTimeStampToDateToStringToDateToIntEndTime(timeInterval: TimeInterval) -> Int {
    let date = Date(timeIntervalSince1970: timeInterval/1000)

    var dateFormater = DateFormatter()
    dateFormater.timeZone = TimeZone(identifier: "UTC")
    dateFormater.dateFormat = "HH:mm:ss"
    let dateString = dateFormater.string(from: date)

    let endTime = dateFormater.date(from: dateString)


        dateFormater.dateFormat = "HH"
        let endHours = Int(dateFormater.string(from: endTime!))
        dateFormater.dateFormat = "mm"
        let endMinutes = Int(dateFormater.string(from: endTime!))
        dateFormater.dateFormat = "ss"
        let endSeconds = Int(dateFormater.string(from: endTime!))



    return endSeconds! + endMinutes! * 60 + endHours! * 3600


}
func convertStringToDateToIntStartTime() -> Int {

    var dateFormater = DateFormatter()
    dateFormater.timeZone = TimeZone(identifier: "UTC")
    dateFormater.dateFormat = "HH:mm:ss"

    let startTime = dateFormater.date(from: "09:00:00")
    dateFormater.dateFormat = "HH"

    let startHours = Int(dateFormater.string(from: startTime!))
    dateFormater.dateFormat = "mm"

    let startMinutes = Int(dateFormater.string(from: startTime!))
    dateFormater.dateFormat = "ss"

    let startSeconds = Int(dateFormater.string(from: startTime!))



    return startSeconds! + startMinutes! * 60 + startHours! * 3600

}