How to use custom date format with JSONDecoder and Codable

Quick background

When writing Swift code interacting with web service, we often use Codable protocol to encode and decode data.

For example, we can decode a json object with two fields id and name by:

func urlCompletion(_ result:Result<Data, Error>) -> Void {
   switch result {
     case .success(let data):
       let entry = JSONDecoder().decode(Entry.self, from: data)
       //To continue processing...
   }
}

struct Entry: Codable, Identifiable {
    var id: Int
    var name: String
}

In this example, the JSON object received is converted to the struct Entry.

Decoding Date

If the JSON object we are receiving contains a Date, it is not difficult to do. We just need to add the field in Date type. However, depending on how the API is implemented, we may need to handle different date format. If you are using ISO-8601 date strings, you can do

func urlCompletion(_ result:Result<Data, Error>) -> Void {
   switch result {
     case .success(let data):
       let decoder = JSONDecoder()
       decoder.dateDecodingStrategy = .iso8601
       let entry = decoder.decode(Entry.self, from: data)
       //To continue processing...
   }
}

struct Entry: Codable, Identifiable {
    var id: Int
    var name: String
    var date: Date
}

Sometimes the JSON object is in custom formats. For example, I have seen web service returning the date in format “yyyy-MM-dd”. We can use DateFormatter to handle this:

func urlCompletion(_ result:Result<Data, Error>) -> Void {
   switch result {
     case .success(let data):
       let decoder = JSONDecoder()
       let format = DateFormatter()
       format.timeZone = .current
       format.dateFormat = "yyyy-MM-dd"
       let entry = decoder.decode(Entry.self, from: data)
       //To continue processing...
   }
}

struct Entry: Codable, Identifiable {
    var id: Int
    var name: String
    var date: Date
}

Leave a ReplyCancel reply