@@ -49,13 +49,13 @@ public extension Encoder {
4949
5050 /// Encode a date for a given key (specified as a string), using a specific formatter.
5151 /// To encode a date without using a specific formatter, simply encode it like any other value.
52- func encode( _ date: Date , for key: String , using formatter: DateFormatter ) throws {
52+ func encode< F : AnyDateFormatter > ( _ date: Date , for key: String , using formatter: F ) throws {
5353 try encode ( date, for: AnyCodingKey ( key) , using: formatter)
5454 }
5555
5656 /// Encode a date for a given key (specified using a `CodingKey`), using a specific formatter.
5757 /// To encode a date without using a specific formatter, simply encode it like any other value.
58- func encode< K: CodingKey > ( _ date: Date , for key: K , using formatter: DateFormatter ) throws {
58+ func encode< K: CodingKey , F : AnyDateFormatter > ( _ date: Date , for key: K , using formatter: F ) throws {
5959 let string = formatter. string ( from: date)
6060 try encode ( string, for: key)
6161 }
@@ -106,14 +106,14 @@ public extension Decoder {
106106 /// Decode a date from a string for a given key (specified as a string), using a
107107 /// specific formatter. To decode a date using the decoder's default settings,
108108 /// simply decode it like any other value instead of using this method.
109- func decode( _ key: String , using formatter: DateFormatter ) throws -> Date {
109+ func decode< F : AnyDateFormatter > ( _ key: String , using formatter: F ) throws -> Date {
110110 return try decode ( AnyCodingKey ( key) , using: formatter)
111111 }
112112
113113 /// Decode a date from a string for a given key (specified as a `CodingKey`), using
114114 /// a specific formatter. To decode a date using the decoder's default settings,
115115 /// simply decode it like any other value instead of using this method.
116- func decode< K: CodingKey > ( _ key: K , using formatter: DateFormatter ) throws -> Date {
116+ func decode< K: CodingKey , F : AnyDateFormatter > ( _ key: K , using formatter: F ) throws -> Date {
117117 let container = try self . container ( keyedBy: K . self)
118118 let rawString = try container. decode ( String . self, forKey: key)
119119
@@ -129,6 +129,24 @@ public extension Decoder {
129129 }
130130}
131131
132+ // MARK: - Date formatters
133+
134+ /// Protocol acting as a common API for all types of date formatters,
135+ /// such as `DateFormatter` and `ISO8601DateFormatter`.
136+ public protocol AnyDateFormatter {
137+ /// Format a string into a date
138+ func date( from string: String ) -> Date ?
139+ /// Format a date into a string
140+ func string( from date: Date ) -> String
141+ }
142+
143+ extension DateFormatter : AnyDateFormatter { }
144+
145+ @available ( iOS 10 . 0 , macOS 10 . 12 , tvOS 10 . 0 , * )
146+ extension ISO8601DateFormatter : AnyDateFormatter { }
147+
148+ // MARK: - Private supporting types
149+
132150private struct AnyCodingKey : CodingKey {
133151 var stringValue : String
134152 var intValue : Int ?
0 commit comments