Swift3でタイムゾーンに応じて自動的に現在時刻と要素を取得して出力
例によって、アップル様から3年前のアプリを作り直して更新するように言われているので、以前作った目覚まし時計アプリのアップデート作業をしています。
で、以前はobjective-cで書いていたので、それをswiftで再度書き直しているところ、swift自体も久しぶりに触ったからswift3での現在時刻の取得方法、特にタイムゾーンを意識した書き方、というのがよくわからなくて色々試行錯誤していたら、以下の2パターンの方法で実行できたので、メモしておきます。
DateFormatter()を使う
まずはDateFormatter()を使う方法です。
let formatter = DateFormatter()
以前のswift2ではNSDateFormatter()で定義していましたが、接頭語のNSが削除されるようになった模様。
色々調べてみると、全体的にNSは使わなくなっているという雰囲気がします。
formatter.timeZone = TimeZone.ReferenceType.local
次にタイムゾーンですが、DateFormatter()型はタイムゾーンが指定できるtimezoneをメンバーに持つので上記のように書き、さらにTimeZone.ReferenceType.localによって、そのiPhoneなりiPadなりに設定されたタイムゾーンが使える。
これによって、世界中に時計アプリを配信する場合であっても問題なく現在時刻が表示されます。
他に国ごとに場合分けしたり時差ごとに場合分けする方法もありますが、非常に面倒です。
formatter.dateFormat = "yyyy-MM-dd-HH-mm-ss"
そしてフォーマットとして、年、月、日、時間、分、秒で取得する場合に、上記のようにハイフンで各々の要素を接続して表示するようにしてみます。
let date1 = Date() let dateStr = formatter.string(from: date1) print(dateStr)
今度は実際の現在時刻の取得です。
date1に現在の日時情報を格納して、上記フォーマッターで定義した形式で出力すると、以下のような結果が得られます。
2016年11月14日3時15分。
目的として、これらを要素ごとに分離して取得したいということがありますので、そうしてみます。
上記フォーマッターで定義したように、各々の要素をハイフンで接続させたので、文字列をハイフンごとに分離させてみます。
let dateComponents = dateStr.components(separatedBy: "-") print(dateComponents)
この結果は次のようになります。
dateComponentsは、各々の要素が格納されたリストとなりました。
というわけで、年であれば配列要素0番目を指定すればいいので、年だけを取り出してみます。
なお、年号は数値なので、できればint型で取得したいので以下のようにします。
let year = Int(dateComponents[0]) print(year)
結果は以下。
swiftを始めたばかりだとビビるかもしれませんが、swiftではある型のものを整数型等の別の型に変換する場合に、オプショナル値という、あるんだかないんだかどっちつかずの値をとるので、実際に使う場合はビックリマークを使って値を確定してあげる必要があります。
print(year!)
こんな感じで各々の要素から時間や秒などを順次取得していけば、色々活用できます。
let month = Int(dateComponents[1]) print(month!) let day = Int(dateComponents[2]) print(day!) let hour = Int(dateComponents[3]) print(hour!) let minite = Int(dateComponents[4]) print(minite!) let second = Int(dateComponents[5]) print(second!)
Calendarを使う
次は、Calendar型を使う場合。
let date2 = Date() let calendar = Calendar.current
Calendar型のcurrentメンバーでオブジェクトを作成してやることにより、現在日時の値を格納した値をcalendarとして定義できます。
calendarから各々の要素を抽出する場合は以下のようにします。
let year2 = calendar.component(.year, from: date2) let month2 = calendar.component(.month, from: date2) let day2 = calendar.component(.day, from: date2) let hour2 = calendar.component(.hour, from: date2) let minute2 = calendar.component(.minute, from: date2) let second2 = calendar.component(.second, from: date2) print(year2) print(month2) print(day2) print(hour2) print(minute2) print(second2)
これによって、例えばMaskClockのように、現在時刻を1秒ごとに取得してそれに応じて画像を変換するといった超優れた時計アプリを世界中に不具合なく配信することができるでしょう。