Swiftでの日付フォーマットのメモ
アプリでDateの扱いは2パターンある
この2つのタイミングで、DateFormatterが使われる。DateFormatterにはdateFormat, calendarやlocaleを設定必要があり、どんなタイミングでどんな値を設定すれば?って感じに混乱になる。
各ものの概念の理解
calendar -> 年月日などの要素の数え方と関係
dateFormat -> 日付情報はどういう風に並んでるのか
locale -> 地域のこと。これで並び方や表記が変わる。localizationが行われる
timezone -> timezoneを設定することで、時間がそのtimezoneの時間に変換される
ここで、私は最初localeがtimezoneの機能持っていると間違えしてた。
localeはあくまでも表示に使われる。
↓すごいいい感じのまとめです。ありがとうございます!
【Swift】Calendar, Locale, TimeZoneなど、国際化周りのクラスを整理 - しめ鯖日記
String -> Date
フォーマット固定の日付文字列を正しい日付のDate型に変換。
let formatter = DateFormatter() // dateFormatをAPIのフォーマットに合わせて設定(rfc3339) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ" // localeをen_US_POSIXに設定 formatter.locale = Locale(identifier: "en_US_POSIX") // calendarを日付文字列だ使ってるcalendarに設定 formatter.calendar = Calendar(identifier: .gregorian) let date = formatter.date(from: "2018-06-16 19:27:30...")
en_US_POSIXとは↓、よくわからないけど…
a locale that's specifically designed to yield US English results regardless of both user and system preferences
rfc3339とはネット上でよく使われてるフォーマットのポリシーみたいなものかな、iso8601もあるけど、どっちがどっちかも正直わからない…rfc3339はiso8601からのものだけわかった
timezoneは文字列に含まれてるため、設定しなくてもいいかな。
Date型をユーザーに見せるStringに変換
Stringに変換するとき、変わるかもって考える必要があるのは2つ
- 表記
- 表示される時間
[表記]
表記はdateFormatを設定することで、固定なフォーマットで表示することができる。しかし、地域によって慣れてる表記が違うため、固定しちゃうとよくない。例えば、地域Aの表記は月/日/年で、地域Bの方が日/月/年の見方が多い場合、固定したフォーマットで月/日/年で表示した場合(06/07/2018)間違えた日付が地域Bのユーザーに取られる。そのため、ちゃんとlocalizationをやる必要がある。
[表示される時間]
timezoneは特に指定する必要がないと思う。ユーザーのtimezoneが使われるはず。
Date -> String
// styleを使う // Localeはcurrentが使われるだしょう let formatter = DateFormatter() formatter.dateStyle = .short formatter.timeStyle = .short let localizedString = formatter.string(from: Date())
// templateを使う // 必要な要素を設定すれば、localizationが勝手にやってくれる let formatter = DateFormatter() formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "yyyyMM", options: 0, locale: nil) return formatter.string(from: self)
templateのcheatsheet