I need to parse javascript dates in swift. Since dates are already stored in some database I cannot change the format of them. I just need to parse them into correct Dates in swift.
Below are examples results of javascript's toString()
function. It depends on Locale/Language
// js
new Date().toString()
'Tue Jun 01 2021 14:11:27 GMT+0900 (JST)'
'Tue Jun 01 2021 14:03:45 GMT+0900 (Japan Standard Time)'
'Mon May 31 2021 17:38:31 GMT+0800 (中国標準時)'
'Mon May 31 2021 19:25:37 GMT+0930 (オーストラリア中部標準時)'
How can I parse this in Swift DateFormatter?
I have tried this:
// swift
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z (zzz)"
Date-> String
conversion looks correct but String -> Date
does not work
// swift
dateFormatter.string(from: Date())
> "Tue Jun 01 2021 14:11:27 GMT+0900 (JST)"
dateFormatter.date(from: "Tue Jun 01 2021 14:11:27 GMT+0900 (JST)")
> nil
Any help is highly appreciated.
As mentioned in the comments by @Sweeper - The timezone name part is implementation dependent - which can be confirmed from the docs
Optionally, a timezone name consisting of:
space
Left bracket, i.e. "("
An implementation dependent string representation of the timezone, which might be an abbreviation or full name (there is no standard for names or abbreviations of timezones), e.g. "Line Islands Time" or "LINT"
Right bracket, i.e. ")"
So we need to - remove the part within parentheses at the end and parse the rest - as mentioned by @Joakim Danielson
Taking this into account, we can do it like this -
extension String {
static private var jsDateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
return formatter
}()
func parsedDate() -> Date? {
let input = self.replacingOccurrences(of: #"\(.*\)$"#, with: "", options: .regularExpression)
return String.jsDateFormatter.date(from: input)
}
}
Tests
func testJSDateParsing() {
[
"Tue Jun 01 2021 14:11:27 GMT+0900 (JST)",
"Tue Jun 01 2021 14:03:45 GMT+0900 (Japan Standard Time)",
"Mon May 31 2021 17:38:31 GMT+0800 (中国標準時)",
"Mon May 31 2021 19:25:37 GMT+0930 (オーストラリア中部標準時)",
].forEach({
if let date = $0.parsedDate() {
print("Parsed Date : \(date) for input : \($0)")
}
else {
print("Failed to parse date for : \($0)")
}
})
}
Output
Parsed Date : 2021-06-01 05:11:27 +0000 for input : Tue Jun 01 2021 14:11:27 GMT+0900 (JST)
Parsed Date : 2021-06-01 05:03:45 +0000 for input : Tue Jun 01 2021 14:03:45 GMT+0900 (Japan Standard Time)
Parsed Date : 2021-05-31 09:38:31 +0000 for input : Mon May 31 2021 17:38:31 GMT+0800 (中国標準時)
Parsed Date : 2021-05-31 09:55:37 +0000 for input : Mon May 31 2021 19:25:37 GMT+0930 (オーストラリア中部標準時)