iOS Swift - Get the Current Local Time and Date Timestamp

IosSwiftDateFirebaseTimestamp

Ios Problem Overview


I'm trying to make an attendance app and I am really confused about date and time in iOS and Firebase.

I use date as Key, this is the structure of my Firebase database.

--Employees
  --Unique_ID
     --Details
          Name: John
     --Attendance
          --dateToday
              Timein: 8:00 AM
              Timeout: 5:00 PM
              BreakStart: 12:00 PM
              BreakFinish: 1:00 PM

This is my code to get the date timestamp I used as Key

 override func viewDidLoad() {
     super.viewDidLoad()
            
     let now = NSDate()
     let nowTimeStamp = self.getCurrentTimeStampWOMiliseconds(dateToConvert: now)

     // I save this dateToday as Key in Firebase
     dateToday = nowTimeStamp
}

       
func getCurrentTimeStampWOMiliseconds(dateToConvert: NSDate) -> String {
    let objDateformat: DateFormatter = DateFormatter()
    objDateformat.dateFormat = "yyyy-MM-dd"
    let strTime: String = objDateformat.string(from: dateToConvert as Date)
    let objUTCDate: NSDate = objDateformat.date(from: strTime)! as NSDate
    let milliseconds: Int64 = Int64(objUTCDate.timeIntervalSince1970)
    let strTimeStamp: String = "\(milliseconds)"
    return strTimeStamp
}

But when I convert it back to date I get 2017-09-22 16:00:00 +0000, which is wrong because it is 23rd of September in my location.

What is the right code to use so that I can get the correct date timestamp and time timestamp?

Ios Solutions


Solution 1 - Ios

For saving Current time to firebase database I use Unic Epoch Conversation:

let timestamp = NSDate().timeIntervalSince1970

and For Decoding Unix Epoch time to Date().

let myTimeInterval = TimeInterval(timestamp)
let time = NSDate(timeIntervalSince1970: TimeInterval(myTimeInterval))

Solution 2 - Ios

If you just want the unix timestamp, create an extension:

extension Date {
    func currentTimeMillis() -> Int64 {
        return Int64(self.timeIntervalSince1970 * 1000)
    }
}

Then you can use it just like in other programming languages:

let timestamp = Date().currentTimeMillis()

Solution 3 - Ios

First I would recommend you to store your timestamp as a NSNumber in your Firebase Database, instead of storing it as a String.

Another thing worth mentioning here, is that if you want to manipulate dates with Swift, you'd better use Date instead of NSDate, except if you're interacting with some Obj-C code in your app.

You can of course use both, but the Documentation states:

> Date bridges to the NSDate class. You can use these interchangeably in > code that interacts with Objective-C APIs.

Now to answer your question, I think the problem here is because of the timezone.

For example if you print(Date()), as for now, you would get:

2017-09-23 06:59:34 +0000

This is the Greenwich Mean Time (GMT).

So depending on where you are located (or where your users are located) you need to adjust the timezone before (or after, when you try to access the data for example) storing your Date:

    let now = Date()
   
    let formatter = DateFormatter()

    formatter.timeZone = TimeZone.current
    
    formatter.dateFormat = "yyyy-MM-dd HH:mm"
   
    let dateString = formatter.string(from: now)

Then you have your properly formatted String, reflecting the current time at your location, and you're free to do whatever you want with it :) (convert it to a Date / NSNumber, or store it directly as a String in the database..)

Solution 4 - Ios

in Swift 5

extension Date {
    static var currentTimeStamp: Int64{
        return Int64(Date().timeIntervalSince1970 * 1000)
    }
}

call like this:

let timeStamp = Date.currentTimeStamp
print(timeStamp)

Thanks @lenooh

Solution 5 - Ios

The simple way to create Current TimeStamp. like below,

func generateCurrentTimeStamp () -> String {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy_MM_dd_hh_mm_ss"
    return (formatter.string(from: Date()) as NSString) as String
}

Solution 6 - Ios

If you code for iOS 13.0 or later and want a timestamp, then you can use:

let currentDate = NSDate.now

Solution 7 - Ios

On expanding @MacacoAzul's answer here is my current working example :

import SwiftUI

struct TimestampDemo: View {
    var body: some View {
        
        Text(getActualTimeStamp(1))
            .padding(10)
       
        Text(getActualTimeStamp(2))
            .padding(10)
        
        Text(getActualTimeStamp(3))
            .padding(10)
        
        Text(getActualTimeStamp(4))
            .padding(10)
    }
    
    
    func getActualTimeStamp(_ tipo:Int) -> String {
            let date = Date()
            let formatter = DateFormatter()
            if tipo == 1{
                formatter.dateFormat = "dd/MM/yyyy"
            } else if tipo == 2{
                formatter.dateFormat = "yyyy-MM-dd HH:mm"
            }else if tipo == 3{
                formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            }
            else if tipo == 4  {
                formatter.dateFormat = "dd-MM-yyyy"
            }

            return formatter.string(from: date)
        }
}

struct TimestampDemo_Previews: PreviewProvider {
    static var previews: some View {
        TimestampDemo()
    }
}

enter image description here

Swift Language Version : 5

Solution 8 - Ios

When we convert a UTC timestamp (2017-11-06 20:15:33 -08:00) into a Date object, the time zone is zeroed out to GMT. For calculating time intervals, this isn't an issue, but it can be for rendering times in the UI.

I favor the RFC3339 format (2017-11-06T20:15:33-08:00) for its universality. The date format in Swift is yyyy-MM-dd'T'HH:mm:ssXXXXX but RFC3339 allows us to take advantage of the ISO8601DateFormatter:

func getDateFromUTC(RFC3339: String) -> Date? {
    let formatter = ISO8601DateFormatter()
    return formatter.date(from: RFC3339)
}

RFC3339 also makes time-zone extraction simple:

func getTimeZoneFromUTC(RFC3339: String) -> TimeZone? {

    switch RFC3339.suffix(6) {

    case "+05:30":
        return TimeZone(identifier: "Asia/Kolkata")

    case "+05:45":
        return TimeZone(identifier: "Asia/Kathmandu")

    default:
        return nil

    }

}

There are 37 or so other time zones we'd have to account for and it's up to you to determine which ones, because there is no definitive list. Some standards count fewer time zones, some more. Most time zones break on the hour, some on the half hour, some on 0:45, some on 0:15.

We can combine the two methods above into something like this:

func getFormattedDateFromUTC(RFC3339: String) -> String? {

    guard let date = getDateFromUTC(RFC3339: RFC3339),
        let timeZone = getTimeZoneFromUTC(RFC3339: RFC3339) else {
            return nil
    }

    let formatter = DateFormatter()
    formatter.dateFormat = "h:mma EEE, MMM d yyyy"
    formatter.amSymbol = "AM"
    formatter.pmSymbol = "PM"
    formatter.timeZone = timeZone // preserve local time zone
    return formatter.string(from: date)

}

And so the string "2018-11-06T17:00:00+05:45", which represents 5:00PM somewhere in Kathmandu, will print 5:00PM Tue, Nov 6 2018, displaying the local time, regardless of where the machine is.

As an aside, I recommend storing dates as strings remotely (including Firestore which has a native date object) because, I think, remote data should agnostic to create as little friction between servers and clients as possible.

Solution 9 - Ios

you can even create a function to return different time stamps depending on your necessity:

func dataatual(_ tipo:Int) -> String {
        let date = Date()
        let formatter = DateFormatter()
        if tipo == 1{
            formatter.dateFormat = "dd/MM/yyyy"
        } else if tipo == 2{
            formatter.dateFormat = "yyyy-MM-dd HH:mm"
        } else {
            formatter.dateFormat = "dd-MM-yyyy"
        }
        
        return formatter.string(from: date)
    } 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTSMView Question on Stackoverflow
Solution 1 - IosSatish BabariyaView Answer on Stackoverflow
Solution 2 - IoslenoohView Answer on Stackoverflow
Solution 3 - Iosuser8606263View Answer on Stackoverflow
Solution 4 - IosdengST30View Answer on Stackoverflow
Solution 5 - IosUser558View Answer on Stackoverflow
Solution 6 - IosJesper SamuelssonView Answer on Stackoverflow
Solution 7 - IosXpressGeekView Answer on Stackoverflow
Solution 8 - IosliquidView Answer on Stackoverflow
Solution 9 - IosMacacoAzulView Answer on Stackoverflow