Skip to content

Instantly share code, notes, and snippets.

@Ikloo
Created June 9, 2020 15:39
Show Gist options
  • Save Ikloo/e0011c99665dff0dd8c4d116150f9129 to your computer and use it in GitHub Desktop.
Save Ikloo/e0011c99665dff0dd8c4d116150f9129 to your computer and use it in GitHub Desktop.
Date formatter with fractional seconds handling from Codable structs
extension Formatter {
static let iso8601: (regular: ISO8601DateFormatter, withFractionalSeconds: DateFormatter) = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
return (ISO8601DateFormatter(), formatter)
}()
}
extension JSONDecoder.DateDecodingStrategy {
static let iso8601withFractionalSeconds = custom {
let container = try $0.singleValueContainer()
let string = try container.decode(String.self)
if let date = Formatter.iso8601.withFractionalSeconds.date(from: string) {
return date
} else if let date = Formatter.iso8601.regular.date(from: string) {
return date
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: " + string)
}
}
}
extension JSONEncoder.DateEncodingStrategy {
static let iso8601withFractionalSeconds = custom {
var container = $1.singleValueContainer()
try container.encode(Formatter.iso8601.withFractionalSeconds.string(from: $0))
}
}
@lukewar
Copy link

lukewar commented Mar 30, 2022

Hey @Ikloo, thanks for publishing it! Do you think it makes sense to update it to the following since .withFractionalSeconds is supported since iOS 11:

static let iso8601: (regular: ISO8601DateFormatter, withFractionalSeconds: ISO8601DateFormatter) = {
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
    return (ISO8601DateFormatter(), formatter)
  }()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment