はじめに
日付を含むJSONをCodableでDate型にする方法をメモしておく。 日付の表現は複数あります。
例えば、下記の表現があります。
- 2020-07-25
- 2020/07/25
- TimeInterval
- その他
変換したいJSONで使われている日付表現に合わせて、設定する必要があります。
Date型への変換
JSONを変換するときに使用するJSONDecoderはデフォルトでは00:00:00 UTC on 1 January 2001からのTimeInterval形式(数値)を変換できます。
その他の日付表現を変換する場合はdateDecodingStrategyプロパティでどのようなフォーマットなのかを指定する必要があります。
デフォルトの変換形式
00:00:00 UTC on 1 January 2001からのTimeInterval形式(数値)を変換できます。
JSONで指定されるTimeIntervalは
00:00:00 UTC on 1 January 2001
からの経過秒数である必要があります。 おそらくデフォルトではDate型の
init(timeIntervalSinceReferenceDate ti: TimeInterval)
https://developer.apple.com/documentation/foundation/nsdate/1409769-init
を使って変換しているのだと思います。
サンプル
import Foundation let jsonString = """ { "createdAt": 617339567.66283596 } """ struct DateObject: Codable { let createdAt: Date } let decoder = JSONDecoder() let result = try decoder.decode(DateObject.self, from: jsonString.data(using: .utf8)!) print(result.createdAt) // 2020-07-25 03:12:47 +0000
ISO8601
dateDecodingStrategyでiso8601を指定します。
サンプル
import Foundation let jsonString = """ { "createdAt": "2020-07-25T03:12:47-00:00" } """ struct DateObject: Codable { let createdAt: Date } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601 let result = try decoder.decode(DateObject.self, from: jsonString.data(using: .utf8)!) print(result.createdAt) // 2020-07-25 03:12:47 +0000
UnixTime(秒指定)
dateDecodingStrategyでsecondsSince1970を指定します。
サンプル
import Foundation let jsonString = """ { "createdAt": 1595646767 } """ struct DateObject: Codable { let createdAt: Date } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .secondsSince1970 let result = try decoder.decode(DateObject.self, from: jsonString.data(using: .utf8)!) print(result.createdAt) // 2020-07-25 03:12:47 +0000
UnixTime(ミリ秒指定)
dateDecodingStrategyでsecondsSince1970を指定します。
サンプル
import Foundation let jsonString = """ { "createdAt": 1595646767000 } """ struct DateObject: Codable { let createdAt: Date } let decoder = JSONDecoder() decoder.dateDecodingStrategy = .millisecondsSince1970 let result = try decoder.decode(DateObject.self, from: jsonString.data(using: .utf8)!) print(result.createdAt) // 2020-07-25 03:12:47 +0000
その他文字列
dateDecodingStrategyでformattedに使用するフォーマットを加えて指定します。
サンプル
import Foundation let jsonString = """ { "createdAt": "2020-07-25 03:12:47+00:00" } """ struct DateObject: Codable { let createdAt: Date } let decoder = JSONDecoder() let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH:mm:ssZ" decoder.dateDecodingStrategy = .formatted(formatter) let result = try decoder.decode(DateObject.self, from: jsonString.data(using: .utf8)!) print(result.createdAt) // 2020-07-25 03:12:47 +0000