Reputation: 49
I have a method that converts my SQL date to "MM-dd-yyyy, HH:mm" in swift. I need to be able to convert this back to "yyyy-MM-dd'T'HH:mm:ss". This will be in server time and also eastern time zone.
Converting to "MM-dd-yyyy, HH:mm":
static func dateView(_ DateString: String) -> String {
var returnDate = ""
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let string = String(DateString)
if let date = dateFormatter.date(from: string) {
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
returnDate = dateFormatter.string(from: date)
}
return returnDate
}
Trying to convert to "yyyy-MM-dd'T'HH:mm:ss":
static func dateToSQLDate(_ DateString: String) -> String {
var returnDate = ""
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM/dd/yy HH:mm"
let string = String(DateString)
if let date = dateFormatter.date(from: string) {
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
//dateFormatter.timeStyle = .short
returnDate = dateFormatter.string(from: date)
}
return returnDate
}
Example would be:
var date = "3/10/16, 10:00AM"
dateToSQLDate(date)
Expected Out: 2016-03-10T10:00:00
Any ideas to what I am doing wrong?
Upvotes: 1
Views: 1045
Reputation: 437917
Others have answered your question, but a few observations:
It is probably prudent to always save your IS8601 timestamp strings in GMT/UTC/Zulu timezone (by setting the timeZone
of your ISO8601 date string formatters to TimeZone(secondsFromGMT: 0)
, perhaps adding the X
qualifier in the string to make it completely unambiguous. It shouldn’t be “server time zone” and probably shouldn’t be the device’s local time zone either.
Even better, I might suggest using the ISO8601DateFormatter
instead, which sets timezones, locales, etc., automatically, making configuration less fragile.
I’d suggest instantiating two separate date formatters, one for the ISO 8601 date format (the one with the T
in it), and another for presenting dates in your UI. While the ISO 8601 date formatter should use the en_US_POSIX
locale (and if you use ISO8601DateFormatter
, that’s taken care of for you), the UI date formatter should not (because you presumably want to show the date in the user’s device’s current locale).
I personally would suggest that your model objects don’t use a string for the date, but rather use a Date
object, instead. So, use ISO8601DateFormatter
when converting between Date
and API strings, store the Date
in your model object, and only use the DateFormatter
with dateStyle
and timeStyle
when presenting the Date
in the user interface.
So this means that rather than two string-to-string routines, you have string-to-date (and vice versa) for each of the two formatters.
Date formatters are notoriously computationally expensive to create. So you might consider creating these two formatters once, save them in ivars, and then you don’t have to repeatedly reinstantiate them.
Upvotes: 0
Reputation: 285180
Your date format is wrong.
Compare the string "3/10/16, 10:00AM"
with the date format "MM/dd/yy HH:mm"
. There are three issues:
a
is missinghh
static func dateToSQLDate(_ string: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM/dd/yy, hh:mma"
guard let date = dateFormatter.date(from: string) else { return "" }
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return dateFormatter.string(from: date)
}
Upvotes: 2
Reputation: 1679
Try this
static func dateToSQLDate(_ DateString: String) -> String {
var returnDate = ""
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let string = String(DateString)
if let date = dateFormatter.date(from: string) {
dateFormatter.dateFormat = "MM/dd/yy HH:mm"
returnDate = dateFormatter.string(from: date)
}
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
return returnDate
}
Upvotes: 0