Reputation: 93
I am trying to parse some json which is the result of an oData connection and I am getting the following response from the server:
"Task_ID":24,"Equipment_ID":3,"Owner_ID":2,"Priority":5,"Date_Due":
"2015-04-08T19:37:56.913","Time_Complete":"2015-04-09T19:37:56","Task_Description"
I am actually interested at the two different date fields I am receiving:
"Date_Due":"2015-04-08T19:37:56.913"
and
"Time_Complete":"2015-04-09T19:37:56"
As we can see, one has the millisecond timestamp and the other one does not.
By looking at the DB, this happens because the millisecond is actually .000 in the database (MS SQL Server) and for whatever reason, the result I receive in my json has this part truncated.
I am not interested in the milliseconds but I would like to have a dateFormat function that can handle both scenarios.
Now I have an obvious answer which is (pre)parse every date field, remove the milliseconds if they are there and then use the following code to format them:
let SQLDateFormatter: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
return formatter
}()
However I would like to know if we can build a formatter that can solve this issue without pre-parsing, something that would be able to take both:
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
and
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
and automatically do the formatting properly.
I have been checking for this issue but could not find anything out there, thanks in advance...
Upvotes: 3
Views: 1641
Reputation: 236370
extension Formatter {
static let iso8601: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
static let iso8601withFractionalSeconds: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
}
extension String {
var date: Date? {
return Formatter.iso8601withFractionalSeconds.date(from: self) ??
Formatter.iso8601.date(from: self)
}
}
"2015-04-08T19:37:56.913".date // "Apr 8, 2015, 4:37 PM"
"2015-04-09T19:37:56".date // "Apr 9, 2015, 4:37 PM"
Upvotes: 3
Reputation: 11435
No, NSDateFormatter
will return nil if the string is not in the exact dateFormat as specified.
What you can do instead of preprocessing the string, is just check if the string you got is with miliseconds or without.
The best way to do this is using Regex. The idea is to create the SQLDateFormatter like you normal, and then check if the string has miliseconds or not. If there are miliseconds included, just change the dateFormat - way better than parsing the string.
if let match = tes.rangeOfString("(\\d{4}-\\d\\d-\\d\\d[T](\\d\\d:){2}\\d\\d.\\d{3})", options: NSStringCompareOptions.RegularExpressionSearch)
{
SQLDateFormatter.format = "yyyy-MM-dd'T'HH:mm:ss.SSS"
}
Upvotes: 3