前回は、ページビューコントローラーを使ったプログラムの例として、万年日めくりカレンダーを作ってみました。ページをめくるたびに、日付が1日進んだり、逆に戻ったりするという単純なものですが、そこでは、当然ながら日付というものをデータとして扱わなければなりません。また、30日の次が同じ月の31日なるのか、次の月の1日になるのか判断するには、現在の一般社会で使われている暦という概念を参照しなければなりません。
iOSには、もちろんそうしたデータを扱うための仕組みが備わっています。前回のプログラムでも、その基本的な機能を使っていました。ただし前回は、あくまでページビューコントローラーの応用例ということで、そのあたりの説明はほとんどはしょってしまいました。そこで今回は、iOSで日時やカレンダーをどのように扱うのかということについて、基本的な説明から始めます。また、それらの応用例を、何か動くプログラムでも示したいので、指定した日時と現在との差分を秒数で表示したり、指定した年月日と今日との日数差を表示するプログラムを作ってみることにします。
カレンダーの種類
まずはカレンダーについて見ていきましょう。Objective-Cでは、NSCalendarというクラスでしたが、SwiftではCalendarという構造体(Structure)として定義されています。通常は、あまりそれらの違いを意識しなくてもいいでしょう。前回の「万年日めくりカレンダー」のプログラムの中にもあったコードですが、とりあえず、「現在の」カレンダーオブジェクトを作ってみましょう。この「現在の」というのは、iPadの「設定」の「一般」の「暦法」で選択されているカレンダーのことでした。
このオブジェクトをcCalという定数に入れるとすれば、
let cCal = Calendar.current
のように書けばいいのでした。
このカレンダーオブジェクトにどのような情報が含まれているかは、Swift Playgroundsのデバッグ機能で、だいたい知ることができます。
表示されている文字から、これはグレゴリオ暦であり、言語は日本語であるらしいことがわかります。では、「Asia/Tokyo」というのは何でしょうか。実は、これはタイムゾーンのことで、言い換えれば地球上のどこで使う(日時を表現する)カレンダーなのかを表しています。また、数字の「1」が2つほど含まれていますが、これらは週が何曜日から始まるのかと、月の最初の週の最少の日数を表すものです。
このようにカレンダーに言語やタイムゾーンの情報が含まれていることは非常に重要です。そのおかげで、過去から現在、未来を結ぶ時間軸上の1点(デイト)が決まったとき、それをどの言語、数字で表せばいいのか、カレンダーという1つのオブジェクトを参照するだけで判断できるからです。とはいえ、厳密にはタイムゾーンの情報は暦とは関係ないので、これは便宜上の措置というものでしょう。
では、そのタイムゾーンがどのようなものなのか、cCalのtimeZoneプロパティの中身を見てみましょう。
この中には、すでに見た「Asia/Tokyo」というタイムゾーンの名前以外に、「JST」という略称や、「32400」という数字が含まれているのが目に付きます。この32400という数字は何を意味するのでしょうか。この数字を見ると、下2桁が00となっていて、何か大きな数字で割り切れそうな気がします。そう、これは3600という大きな約数を持っています。3600と聞けばピンと来るでしょうか。60×60で、1時間の秒数を表しています。つまり32400は9時間を表すことになります。これは、日本標準時(JST)のグリニッジ標準時(GMT)との時差として知られた数字です。
要するに、タイムゾーンには、その名前と時差の情報が含まれているわけです。もう1つ「false」というのが気になるかもしれません。これは、いわゆる「夏時間」があるかどうかを表しています。日本は、その仕組みを採用していないので、falseになっているわけです。
ここで別のカレンダーを見て見ましょう。カレンダーのオブジェクトを作成する際には、iPadの設定に合わせたcurrentを指定する以外に、カレンダーの種類そのものを指定することもできます。例えば、日本独自のカレンダー、つまり和暦は、Calendar.Identifierのタイプとして「japanese」を指定して、
let jCal = Calendar(identifier: .japanese)
のようにしてオブジェクトjCalを作成することができます。
このカレンダーの中身を、前と同じように見て見ましょう。
iPadに設定してあるcurrentと比べると、「gregorian」だったところが「japanese」となっています。これがこのカレンダーのIDですが、他の部分は同じように見えます。試しにtimeZoneプロパティの中身を見ても、前とまったく同じです。
このIDの違いがどのような効果をもたらすのかについては、もう少し後で見てみることにしましょう。
この連載の記事
- 第100回 SceneKitの物理現象シミュレーションとアニメーションをARKitに持ち込む
- 第99回 「物理学体」と「物理学場」を設定して物理現象をシミュレーション
- 第98回 SceneKitのノードに動きを加えるプログラム
- 第97回 いろいろな形のノードをシーンの中に配置する
- 第96回 SceneKitの基礎シーンビュー、シーン、ノードを理解する
- 第95回 現実世界の床にボールや自動車のモデルを配置する
- 第94回 ARKitを使って非現実世界との融合に備える
- 第93回 ARKitが使えるiPadを識別するプログラム
- 第92回 Swift Playgrounds 2.1での問題点をまとめて解消する
- 第91回 iPadの内蔵カメラで撮影した写真を認識するプログラム
- この連載の一覧へ