0

This is the database below. I need to take the 'caption' child which is a timestamp and convert it into date format in Xcode.

"UserS" : {
    "K1eqsVZfKGgIf0sS1UZcPNxY62x1" : {
      "Education" : "William Taft Elementary",
      "PhotoPosts" : "https://firebasestorage.googleapis.com/v0/b/daylike-2f938.appspot.com/o/images%2FPhotoPosts?alt=media&token=fd92856e-f7d2-4558-82c4-ee49f580icc5e",
      "caption" : 1563277511065,
      "users" : "jane19@aol.com"
    },

This is what I have under super view did load.

let databaseRef = Database.database().reference()
    let uid = Auth.auth().currentUser!.uid
    databaseRef.child("UserS").child(uid).child("caption").observeSingleEvent(of: .value, with: { (snapshot) in
        guard let message = snapshot.value as? [String:String] else { return }
        let caption = message["caption"]
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"
        guard let date = dateFormatter.date(from: caption!) else {
        fatalError("ERROR: Date conversion failed due to mismatched format.")
    }
        if (snapshot.exists()){

            print ("mmmmmmm")
        }else{

            print("badddddd")

        }


    })

At the end I want to print out the timestamp in date format so that I can check it it is 24 hours old.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
noname87f
  • 19
  • 4

2 Answers2

3

"13 digit timestamp" is just and number of milliseconds since 1st of January 1970 UTC.

Date already has initializer for timestamps since that timepoint. Only difference is it's number of seconds, not milliseconds.

Therefore only thing you should do is to divide it by 1000:

// skipping unrelevant boilerplate

// assuming caption is Int
let date = Date(timeIntervalSince1970: TimeInterval(caption)/1000.0) // for `1563277511065` it would be `"Jul 16, 2019 at 11:45 AM"`(UTC)

// skipping unrelevant boilerplate

EDIT:

To check if date from timestamp is not "older" than 24 hours you have several options:

  1. Get difference between the date and now and check if it's under 24 hours:

    let secondsInDay = 86400
    if (-date.timeIntervalSinceNow < secondsInDay) { … } // negative, because that date would be in the past
    
  2. Get one day before using calendar:

    let calendar = Calendar.autoupdatingCurrent // or whatever you prefer
    let dayBefore = calendar.date(
                                  byAdding: .day, 
                                  value: -1, 
                                  to: Date(), 
                                  wrappingComponents: true)!
    
    if (date > dayBefore) { … }
    
user28434'mstep
  • 6,290
  • 2
  • 20
  • 35
  • Thanks. I printed it and got 11:41 not 11:45. Once this part is done, do you know how to compare the timestamp with present time and check if 24 hours passed? – noname87f Jul 16 '19 at 14:20
1

Since you listen to UserS->caption then snapshot.value is an Int . so you need

databaseRef.child("UserS").child(uid).child("caption").observeSingleEvent(of: .value, with: { (snapshot) in
    guard let caption = snapshot.value as? Int else { return }
    print(caption)
    let date = Date(timeIntervalSince1970: TimeInterval(caption)/1000.0)
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss.SSSSxxx"
    let res = dateFormatter.string(from: date) 
    print(res) 
}

Edit:

if Calendar.current.dateComponents([.day], from:date, to: Date()).day! > 0 {
     /// at least 1 day passed 
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • Thanks! That did make the 13 digit print successfully but what about the rest of the code to get it to date format? As is you'd get an error in the line "guard let date ...." of Cannot convert value of type 'Int' to expected argument type 'String' – noname87f Jul 16 '19 at 14:08
  • Adding more then 3 fraction digits is pointless. https://stackoverflow.com/a/46458771/2303865 – Leo Dabus Jul 16 '19 at 14:09
  • I see the answer is longer now, I'll look at the rest. – noname87f Jul 16 '19 at 14:10
  • @LeoDabus will check it – Shehata Gamal Jul 16 '19 at 14:33
  • Do you know how to then compare the snapshot with current time to determine if 24 hours passed? – noname87f Jul 16 '19 at 14:38
  • @Leo Dabus - ideally if it is next calendar day at wherever in the world the user is. But that is probably a bit complicated so 24 hours or maybe 16 would work too. – noname87f Jul 16 '19 at 14:49
  • @noname87f `Calendar` has a specific method called `isDateInYesterday` exactly for that purpose. https://developer.apple.com/documentation/foundation/calendar/2293566-isdateinyesterday – Leo Dabus Jul 16 '19 at 14:57
  • @ Leo Dabus - That's really cool. Does it work in whatever timezone the user is? Edit: Looks to be. I checked the link. It says according to the Calendar locale – noname87f Jul 16 '19 at 14:59
  • yes you can also create a custom locale calendar. Btw you might be interested in tis post https://stackoverflow.com/a/43664156/2303865 – Leo Dabus Jul 16 '19 at 15:04
  • Thanks. That's really cool that it can do all those in that link. I guess it is the same in principle as the 2nd method that user28434 posted above. – noname87f Jul 16 '19 at 15:09
  • @Sh_Khan - for firebaseDate, shouldn't it be date. firebaseDate is unresolved identifier. – noname87f Jul 16 '19 at 15:14
  • yes it's `date` i mean a variable date which is from the firebase – Shehata Gamal Jul 16 '19 at 15:16
  • @Sh_Khan , just so I understand perfectly, so it is correct to write "from:date" in there in the place of "from:firebaseDate" because we defined the "firebaseDate" as "date" in the previous part? – noname87f Jul 16 '19 at 15:20
  • yes it's `if Calendar.current.dateComponents([.day], from:date, to: Date()).day! > 0` – Shehata Gamal Jul 16 '19 at 15:23
  • gotcha, thanks. It looks to be working because it is correctly saying that date for this user is not not more than 1 day, ie the else statement is printed. – noname87f Jul 16 '19 at 15:29
  • @Sh_Khan - just going back to what you said in the first line of you answer (it needing to be Int. When I created the timestamp I used: let caption = ServerValue.timestamp() as! [String : Any]. Is that still fine with your Int line? – noname87f Jul 16 '19 at 15:53
  • `ServerValue.timestamp()` is a command that lets server store it's current timestamp , if it works with you in set & read then it's ok – Shehata Gamal Jul 16 '19 at 15:54
  • Great, thanks for the help. I assume it it because it was set to [String : Any] that it works. – noname87f Jul 16 '19 at 18:02