3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftAdvent Calendar 2022

Day 4

Dateを文字列として正確にEncode/Decodeするのは不可能

Last updated at Posted at 2022-12-03

APIから日付をDecodeする(Encode)

TwitterなどのAPIから日付を取得(Decode)する際に、日付が文字列形式のことがあります。
その時のDecode/ Encodeの実装時には注意が必要です。

Date(日付)は情報量が多く、人間が簡単に見やすい形式yyyy-MM-dd'T'HH:mm:ssZZZZZに変換してJSONにする(Encode/Decode)のでは、情報量が落ちてしまいます。

情報量が落ちてしまう例

このJSONを生成するには、JSONEncoderのdateEncodingStrategyを設定する必要があります。

{
  "name":"zunda",
  "createdAt":"2022-12-02T10:12:19Z"
}
struct User: Codable, Equatable {
  let name: String
  let createdAt: Date
}

let user = User(name: "zunda", createdAt: Date())
    
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let data = try encoder.encode(user)
    
print(String(data: data, encoding: .utf8)!)

生成したJSONをDecodeして同じ日付であるかをチェックする

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let decodedUser = try decoder.decode(User.self, from: data)

// 比較
let sameDate = user.createdAt == decodedUser.createdAt // falseになる

// ここで情報量が落ちていることが確認できる
print(user.createdAt.timeIntervalSinceReferenceDate) // 691669442.562633
print(decodedUser.createdAt.timeIntervalSinceReferenceDate) // 691669442.0 

情報量を落とさない方法

標準の方法では実は情報量は落とさず、Encode/Decodeすることができます。
しかし人間が見ても簡単には、日付がわかりません。
標準方法でEncodeすると以下のような形になります。これはDecodeしても情報量が落ちません。

{
    "name":"zunda",
    "createdAt":691668705.64202905
}
let user = User(name: "zunda", createdAt: Date())
    
let encoder = JSONEncoder()
let data = try encoder.encode(user)

print(String(data: data, encoding: .utf8)!)

let decoder = JSONDecoder()
let decodedUser = try decoder.decode(User.self, from: data)

print(user.createdAt.timeIntervalSinceReferenceDate)
print(decodedUser.createdAt.timeIntervalSinceReferenceDate)

Encode/ Decodeのテストができない

作成したモデルをEncodeして、Decodeすることで、EncodeとDecodeの整合性をテストするといったことが文字列日付を使用しようとするとできないです。

テスト時はdateDecodingStrategy, dateEncodingStrategyを設定しないなどで対処するしかないかもしれません。

3
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?