I'm trying to parse this
2017-01-23T10:12:31.484Z
using native ISO8601DateFormatter
class provided by iOS 10
but always fails. If the string not contains milliseconds, the Date
object is created without problems.
I'm tried this and many options
combination but always fails...
let formatter = ISO8601DateFormatter() formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.formatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withColonSeparatorInTimeZone, .withFullTime]
Any idea? Thanks!
ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).
Yes, it is valid.
The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long ( YYYY-MM-DDTHH:mm:ss. sssZ or ±YYYYYY-MM-DDTHH:mm:ss. sssZ , respectively). The timezone is always zero UTC offset, as denoted by the suffix Z .
Prior to macOS 10.13 / iOS 11 ISO8601DateFormatter
does not support date strings including milliseconds.
A workaround is to remove the millisecond part with regular expression.
let isoDateString = "2017-01-23T10:12:31.484Z" let trimmedIsoString = isoDateString.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression) let formatter = ISO8601DateFormatter() let date = formatter.date(from: trimmedIsoString)
In macOS 10.13+ / iOS 11+ a new option is added to support fractional seconds:
static var withFractionalSeconds: ISO8601DateFormatter.Options { get }
let isoDateString = "2017-01-23T10:12:31.484Z" let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] let date = formatter.date(from: isoDateString)
For people that are not ready to go to iOS 11 yet, you can always create your own formatter to handle milliseconds, e.g.:
extension DateFormatter { static var iSO8601DateWithMillisec: DateFormatter { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" return dateFormatter } }
Usage:
let formater = DateFormatter.iSO8601DateWithMillisec let date = formater.date(from: "2017-01-23T10:12:31.484Z")! print(date) // output: 2017-01-23 10:12:31 +0000
It is slightly more elegant than writing a regex to strip out the milliseconds from the input string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With