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 datab
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))
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.