试图在Swift中将Firebase时间戳转换为NSDate

Foo*_*ook 18 ios firebase swift

我正在尝试在Swift应用中使用Firebase时间戳.我想将它们存储在我的Firebase中,并在我的应用中将它们用作本机NSDate对象.

文档说他们是unix epoch时间,所以我尝试过:

NSDate(timeIntervalSince1970:FirebaseServerValue.timestamp)
Run Code Online (Sandbox Code Playgroud)

没有运气.

这个:

FirebaseServerValue.timestamp
Run Code Online (Sandbox Code Playgroud)

回报

0x00000001199298a0
Run Code Online (Sandbox Code Playgroud)

根据调试器.通过这些时间戳的最佳方法是什么?

小智 36

ServerValue.timestamp()与在Firebase中设置普通数据的工作方式略有不同.它实际上不提供时间戳.相反,它提供了一个值,告诉Firebase服务器用时间填充该节点.通过使用此功能,您的应用程序的时间戳将全部来自一个来源Firebase,而不是用户设备所说的任何内容.

当您获得值(来自观察者)时,您将获得自纪元以来毫秒的时间.您需要将其转换为秒以创建NSDate.这是一段代码:

let ref = Firebase(url: "<FIREBASE HERE>")

// Tell the server to set the current timestamp at this location.
ref.setValue(ServerValue.timestamp()) 

// Read the value at the given location. It will now have the time.
ref.observeEventType(.Value, withBlock: { 
    snap in
    if let t = snap.value as? NSTimeInterval {
        // Cast the value to an NSTimeInterval
        // and divide by 1000 to get seconds.
        println(NSDate(timeIntervalSince1970: t/1000))
    }
})
Run Code Online (Sandbox Code Playgroud)

您可能会发现您收到两个非常接近时间戳的事件.这是因为SDK会在从Firebase收到回复之前对时间戳进行最佳"猜测".一旦它从Firebase听到实际值,它将再次提升Value事件.


Rau*_*spe 20

对于我在 swift 5 中使用的另一个类:

import FirebaseFirestore
init?(document: QueryDocumentSnapshot) {
        let data = document.data()
       guard let stamp = data["timeStamp"] as? Timestamp else {
            return nil
        }
       let date = stamp.dateValue()
}
Run Code Online (Sandbox Code Playgroud)

  • 这应该是今天公认的答案。设置要存储在 Firebase 中的数据时,请使用日期。检索它时,使用此答案将时间戳转换为日期。 (3认同)

Doe*_*ata 7

这个问题很老,但我最近遇到了同样的问题,所以我会提供一个答案.

在这里,您可以看到我如何将时间戳保存到Firebase数据库

 let feed = ["userID": uid,
             "pathToImage": url.absoluteString,
             "likes": 0,
             "author": Auth.auth().currentUser!.displayName!,
             "postDescription": self.postText.text ?? "No Description",
             "timestamp": [".sv": "timestamp"],
             "postID": key] as [String: Any]

 let postFeed = ["\(key)" : feed]

 ref.child("posts").updateChildValues(postFeed)
Run Code Online (Sandbox Code Playgroud)

特别相关的代码行是 "timestamp": [".sv": "timestamp"],

这会将时间戳保存为数据库中的double.这是以毫秒为单位的时间,因此您需要除以1000以获得以秒为单位的时间.您可以在此图像中看到示例时间戳. Firebase时间戳

要将此double转换为Date,我编写了以下函数:

func convertTimestamp(serverTimestamp: Double) -> String {
        let x = serverTimestamp / 1000
        let date = NSDate(timeIntervalSince1970: x)
        let formatter = DateFormatter()
        formatter.dateStyle = .long
        formatter.timeStyle = .medium

        return formatter.string(from: date as Date)
    }
Run Code Online (Sandbox Code Playgroud)

这给出了一个如下所示的时间戳: 时间戳