Swift,Objective-Cプログラミング ~ iOS ~

Objective-C,Swift,Apple Watchなどのプログラミング

【Swift】日付を含むJSONをCodableでDate型に変換する

はじめに

日付を含む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