Firebase & Swift - Date saved with UTC -7? - ios

I'm trying to understand how exactly dates are saved in the CloudFirestore of Firebase...
When I put the current date in the database dateToSAve = Date() , this date is stored with UTC-7:
But in someone in France for example, want to save data on Firebase, it will be the current date -9 hours to conform with the UTC -7
And sometimes, because of that, it can be a different day...
Do you know how to handle this problem? I would like to save in the database, the current date of the user.

You should not store date object in database, instead you should save timestamp in UTC 0. And after retrieving that timestamp you can convert it back into date with the time portion in your current time zone.
For getting timestamp in UTC 0:
let timestamp = Date().timeIntervalSince1970
And for converting timestamp back to date with the time portion in your current timezone:
// gives date with time portion in UTC 0
let date = Date(timeIntervalSince1970: timestamp)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM-dd-yyyy" // change to your required format
dateFormatter.timeZone = TimeZone.current
// date with time portion in your specified timezone
print(dateFormatter.string(from: date))

Related

String to date with UTC timezone

I am struggling with Date and I'm assuming is TimeZone.
Currently I get from my backend a string like this "2020-04-07" and when I try to convert it to date it turns into 2020-04-06 22:00:00 +0000. I am in Spain (UTC+2) which I guess this is why it removes 2 hours?
This is my date formatter:
var dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
dateFormatter.timeZone = TimeZone.current
return dateFormatter
}()
And I call it dateFormatter.date(from: startDateString)
I am setting my current timezone but seems to be ignoring it or am I missing something?
I have followed a lot of answers from here but it's always the same result.
Thank you
The Date object does not have any inherent locale / time zone. It just represents a moment in time. If you want to see that Date as a string in a specific locale/time zone you have to use a date formatter. Or there's descriptionWithLocale. If you use print it will print a debug description of the Date instance in UTC.

How to change back year that change into 2000 after using date format

hi I want to get current hour and minute from Date(), so I need to format it into string and want to bring back into date again. But after I try to convert to date the year change into 2000, how can I got back to current year.
//date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.timeZone = TimeZone.current
// Get current time and format it to compare
var currentTime = Date() //Get current time
let currentTimeStr = dateFormatter.string(from: currentTime) //get current time only hour and minute
currentTime = dateFormatter.date(from: currentTimeStr)! //this is where the problem because the year change into 1 January 2000
From what I read in the comments, I think you want both the current time in a Date object and also a string with only hours and minutes in "HH:MM" format.
The problem comes from trying to use a formatter that doesn't have a year specified. You are overwriting the currentTime from a string that doesn't have a year (or day, or month) defined, so it defaults to Jan 1st 2000 (the hours and minutes should be correct).
You're also saying you need to format it into a String, and then go back to a Date object. You don't, you already have all the data you need in the Date object, so keep it around and use it when you need to. If this means creating a bunch of DateFormatters all over your project, you can always extend Date to have a function or variable that returns the string with the format you want.
extension Date {
var hoursAndMinutesString: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
dateFormatter.timeZone = TimeZone.current
return dateFormatter.string(from: self)
}
}
Then just call the function from the Date object when you need to, like this:
currentTime.hoursAndMinutesString

Remove time component from TimeInterval in Swift?

I have a time component coming from a Json. I am trying to group objects according to their time posted.
I have a time interval like 1540432146 which is a double.
I am converting it to Date type using
guard let timeInMilliseconds = lastUpdateOn as? Double else {return NSDate()}
let timeInSeconds = timeInMilliseconds / 100000
print(timeInSeconds)
// get the Date
let dateTime = NSDate(timeIntervalSince1970: timeInSeconds)
Hence I am getting 2018-10-25 10:54:20.325076+0900 as the output.
Is it possible to remove the Time component of this and again converting the Date type back to TimeIntervalSincel1970 as I will using it later to sort my elements in an array and it would be easier to compare Double
func getTime(lastUpdateOn:Any) -> NSDate{
guard let timeInMilliseconds = lastUpdateOn as? Double else {return NSDate()}
let timeInSeconds = timeInMilliseconds / 100000
// get the Date
let dateTime = NSDate(timeIntervalSince1970: timeInSeconds)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
let datenew = dateFormatter.string(from: dateTime as Date)
let newDate = dateFormatter.date(from: datenew)
print(newDate)
return dateTime
}
This is the function I tried but it returns value (1970-06-27 15:00:00 +0000) always. What am I doing wrong ?
If your only goal is to compare different dates to see which one comes first, simply convert the Int Unix Timestamps from your JSON to Date objects with:
let aDate = Date(timeIntervalSince1970: Double(timestamp)/1000.0)
You can compare Date objects directly using >, =, <, etc, and the result will compare the dates down to the millisecond.
You can also compare your Unix timestamp values directly and the results will be identical to comparing timestamps that you've converted to Date objects.
If you want to compare Date objects just by month/day/year, its more complicated.
A Cocoa Date ALWAYS represents an instant in time, all over the world. Internally, it's represented as a number of seconds since the iOS "epoch date" (midnight on January 1st, 2001 in UTC) Unix uses a different epoch date, but using "timeIntervalSince1970" and it's variants lets you work with Cocoa Date objects and Unix epoch dates.
There is no such thing as a Date "without a time component". There are various ways you could "normalize" your dates: You can convert a date to a date string that only has the month/day/year; you can force all Date values to exactly midnight on their month/day/year in a given timezone, or you could extract month/day/year DateComponents from your Date. (Search on "DateComponents" in the Xcode help system, and also search for "DateComponents" in the Calendar class reference, as many of the functions that let you do calculations on Dates and DateComponents are provided by the Calendar class.)
Note that the day/month/year that a Unix numeric timestamp falls on is often different depending on your time zone. Right now it's 22:47 EDT on 24 October here in the DC suburbs. I just computed the Unix timestamp for the current time and got 1540435644000. In Japan, 1540435644000 is 25 October. (From my perspective, it's already tomorrow in Japan). So 2 Unix timestamps might be on the same day/month/year in Japan but on different day/month/years where I live, or visa-versa.

Get UTC Date To Local Date in swift iOS

I am trying to convert UTC Date to local date in swift but after get UTC To Local date in string i convert that string to again in NSDate but i am always getting in UTC date format, below is my code
Date : in UTC : 2016-07-20 18:30:00 +0000
I am trying this date in local date, check below code:
let dateInUTC = NSDate()
let seconds: Int = NSTimeZone.systemTimeZone().secondsFromGMT
print(seconds)
let localDateFormatter: NSDateFormatter = NSDateFormatter()
localDateFormatter.dateFormat = "MM/dd/yyyy HH:mm"
localDateFormatter.timeZone = NSTimeZone(forSecondsFromGMT: seconds)
let lastDate: String = localDateFormatter.stringFromDate(dateInUTC)
print(lastDate)
at this time i am getting “07/12/2016 16:56:36 GMT+5:30”, means i got local date in string but i want this date in NSDate so again i convert this string date in NSDate,check below
let getDate:NSDate = localDateFormatter.dateFromString(lastDate)!
print(getDate)
but at this stage again i got date in UTC (2016-07-12 11:26:36 +0000) but i want in local date,
I tried a lot of times in Swift but not getting local date from string,this line of code i used in objective-c, its working fine in obj-c but when i am trying in swift i always get UTC date,suggest me and give me right way to sol this.
NSDates don't save time zone information. You always have to use the dateFormatter with time zone when retrieving.

NSDateFormatter decreases the day of date

I need to store Date variable in CoreData in iOS
I need to store the Date only without the Time, So I made a formatter that discard the time partition from the NSDate variable.
But I have a strange result:
This is my code:
let dateStr = "2016-02-14 11:27:01"
let df2 = NSDateFormatter()
df2.timeZone = NSTimeZone.defaultTimeZone()
df2.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(dateStr)
if let date = df2.dateFromString(dateStr) {
df2.dateFormat = "yyyy-MM-dd"
print("-> \(df2.dateFromString(df2.stringFromDate(date)))")
}
and this is the output:
2016-02-14 11:27:01
-> Optional(2016-02-13 20:00:00 +0000)
Why does the formatter decrease the day by one ?
I tried many dates with same issue
Your time zone is obviously UTC+4.
To get UTC set the time zone accordingly.
df2.timeZone = NSTimeZone(forSecondsFromGMT: 0)
But although you see a date 4 hours ago the NSDate object is treated correctly depending on your time zone. The print command displays always UTC ignoring the time zone information, because NSDate is just a wrapper for a Double number.

Resources