ios swift date swift3 ios10

ios - string to date swift 4



ISO8601DateFormatter no analiza la cadena de fecha ISO (3)

Antes de macOS 10.13 / iOS 11 ISO8601DateFormatter no admite cadenas de fecha, incluidos los milisegundos.

Una solución es eliminar la parte de milisegundos con expresiones regulares.

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)

En macOS 10.13+ / iOS 11+ se agrega una nueva opción para soportar segundos fraccionarios:

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)

Estoy tratando de analizar esto

2017-01-23T10: 12: 31.484Z

el uso de la clase nativa ISO8601DateFormatter proporcionada por iOS 10 pero siempre falla. Si la cadena no contiene milisegundos, el objeto Date se crea sin problemas.

He probado esta combinación y muchas options pero siempre falla ...

let formatter = ISO8601DateFormatter() formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.formatOptions = [.withInternetDateTime, .withDashSeparatorInDate, .withColonSeparatorInTime, .withColonSeparatorInTimeZone, .withFullTime]

¿Alguna idea? ¡Gracias!


Me encontré con el mismo problema hace unos meses. Y aquí está mi solución para referencia:

// ***************************************** // MARK: - Formatter extension // ***************************************** extension Formatter { static let iso8601: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.timeZone = TimeZone.current formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] return formatter }() static let iso8601NoSecond: ISO8601DateFormatter = { let formatter = ISO8601DateFormatter() formatter.timeZone = TimeZone.current formatter.formatOptions = [.withInternetDateTime] return formatter }() } // ***************************************** // MARK: - ISO8601 helper // ***************************************** func getDateFrom(DateString8601 dateString:String) -> Date? { if let date = Formatter.iso8601.date(from: dateString) { return date } if let date = Formatter.iso8601NoSecond.date(from: dateString) { return date } return nil } // ***************************************** // usage // ***************************************** let d = getDateFrom(DateString8601: "2017-01-23T10:12:31.484Z") print("2017-01-23T10:12:31.484Z millis= ", d?.timeIntervalSinceReferenceDate) let d2 = getDateFrom(DateString8601: "2017-01-23T10:12:31Z") print("2017-01-23T10:12:31Z millis= ", d2?.timeIntervalSinceReferenceDate) // ***************************************** // result // ***************************************** 2017-01-23T10:12:31.484Z millis= Optional(506859151.48399997) 2017-01-23T10:12:31Z millis= Optional(506859151.0)


Quizás esto ayude a decodificar formatos ligeramente diferentes:

extension JSONDecoder { enum DateDecodeError: String, Error { case invalidDate } static var bestDateAttemptDecoder: JSONDecoder { let decoder = JSONDecoder() decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in let container = try decoder.singleValueContainer() if let dateSecs = try? container.decode(Double.self) { return Date(timeIntervalSince1970: dateSecs) } if let dateSecs = try? container.decode(UInt.self) { return Date(timeIntervalSince1970: TimeInterval(dateSecs)) } let dateStr = try container.decode(String.self) let isoFormatter = ISO8601DateFormatter() isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] if let date = isoFormatter.date(from: dateStr) { return date } isoFormatter.formatOptions = [.withInternetDateTime ] if let date = isoFormatter.date(from: dateStr) { return date } log.warning("Cannot decode date"); throw DateDecodeError.invalidDate }) return decoder } }

Desde: https://gist.github.com/th3m477/442a0d1da6354dd3b84e3b71df5dca6a