【iOS】DateとStringの相互変換の注意点

今更ですが混乱することがあるのでまとめておく

String->Date

タイムゾーンなどの情報がない場合は現在の端末設定から自動的に タイムゾーンを考慮したDateが返ってくる
※ 地域の設定が日本の場合

let dateString = "2018/01/01 12:00"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm"
print(formatter.date(from: dateString)!)
結果
2018-01-01 03:00:00 +0000

基本的にDateFormatterにタイムゾーンを指定しない場合は
日本の場合UTC+9時間なので以下のようになる(DateはそもそもUTC+0)
Date -> String +9時間
String -> Date - 9時間

ちゃんとタイムゾーンが指定されていればそのタイムゾーンを考慮した時刻を得ることができる(RFC3339)

let dateString = "2018-01-01T12:00:00+09:00"

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
print(formatter.date(from: dateString)!)
結果
2018-01-01 03:00:00 +0000
let dateString = "2018-01-01T12:00:00+00:00"

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
print(formatter.date(from: dateString)!)
結果
2018-01-01 12:00:00 +0000

Date->String

DateFormatterのlocaleにen_US_POSIXを指定すること。そうしないと和暦などの設定によっては正しく変換できない

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX") // これ

まとめ

  • タイムゾーンの指定しないと端末の地域設定から自動的に考慮した結果が返される
  • DateはUTC+0
  • DateFormatterのlocaleにen_US_POSIXを指定しないと Date->String の時に意図しない結果になる