このページの本文へ

Swift Playgroundsで学ぶiOSプログラミング第73回

カレンダーとデイトを理解

Swiftで秒数・日数計算機を作る

2018年01月22日 17時00分更新

文● 柴田文彦 編集●吉田ヒロ

  • この記事をはてなブックマークに追加
  • 本文印刷

 前回は、ページビューコントローラーを使ったプログラムの例として、万年日めくりカレンダーを作ってみました。ページをめくるたびに、日付が1日進んだり、逆に戻ったりするという単純なものですが、そこでは、当然ながら日付というものをデータとして扱わなければなりません。また、30日の次が同じ月の31日なるのか、次の月の1日になるのか判断するには、現在の一般社会で使われている暦という概念を参照しなければなりません。

 iOSには、もちろんそうしたデータを扱うための仕組みが備わっています。前回のプログラムでも、その基本的な機能を使っていました。ただし前回は、あくまでページビューコントローラーの応用例ということで、そのあたりの説明はほとんどはしょってしまいました。そこで今回は、iOSで日時やカレンダーをどのように扱うのかということについて、基本的な説明から始めます。また、それらの応用例を、何か動くプログラムでも示したいので、指定した日時と現在との差分を秒数で表示したり、指定した年月日と今日との日数差を表示するプログラムを作ってみることにします。

カレンダーの種類

 まずはカレンダーについて見ていきましょう。Objective-Cでは、NSCalendarというクラスでしたが、SwiftではCalendarという構造体(Structure)として定義されています。通常は、あまりそれらの違いを意識しなくてもいいでしょう。前回の「万年日めくりカレンダー」のプログラムの中にもあったコードですが、とりあえず、「現在の」カレンダーオブジェクトを作ってみましょう。この「現在の」というのは、iPadの「設定」の「一般」の「暦法」で選択されているカレンダーのことでした。

 このオブジェクトをcCalという定数に入れるとすれば、

let cCal = Calendar.current

のように書けばいいのでした。

 このカレンダーオブジェクトにどのような情報が含まれているかは、Swift Playgroundsのデバッグ機能で、だいたい知ることができます。

現在iPadに設定されているカレンダーのオブジェクトを作成して中身を見てみると、グレゴリオ暦、日本語、東京のタイムゾーンが設定されていることがわかります

 表示されている文字から、これはグレゴリオ暦であり、言語は日本語であるらしいことがわかります。では、「Asia/Tokyo」というのは何でしょうか。実は、これはタイムゾーンのことで、言い換えれば地球上のどこで使う(日時を表現する)カレンダーなのかを表しています。また、数字の「1」が2つほど含まれていますが、これらは週が何曜日から始まるのかと、月の最初の週の最少の日数を表すものです。

 このようにカレンダーに言語やタイムゾーンの情報が含まれていることは非常に重要です。そのおかげで、過去から現在、未来を結ぶ時間軸上の1点(デイト)が決まったとき、それをどの言語、数字で表せばいいのか、カレンダーという1つのオブジェクトを参照するだけで判断できるからです。とはいえ、厳密にはタイムゾーンの情報は暦とは関係ないので、これは便宜上の措置というものでしょう。

 では、そのタイムゾーンがどのようなものなのか、cCalのtimeZoneプロパティの中身を見てみましょう。

現在のカレンダーのタイムゾーンには、タイムゾーンの名前以外に、その略称(JST)や、時差の値が秒数で記録されています

 この中には、すでに見た「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を作成することができます。

 このカレンダーの中身を、前と同じように見て見ましょう。

カレンダーのオブジェクトは、暦のIDを指定して作成することもできます。.japaneseを指定して作成したカレンダーは、それ以外のデータは上の現在のカレンダーとぱっと見は違わないように見えます

 iPadに設定してあるcurrentと比べると、「gregorian」だったところが「japanese」となっています。これがこのカレンダーのIDですが、他の部分は同じように見えます。試しにtimeZoneプロパティの中身を見ても、前とまったく同じです。

現在のカレンダーも、.japaneseのカレンダーも、少なくともタイムゾーンのデータはまったく同じであることがわかります。それは、どちらも地球上の日本での日時を表示するためのものだからです

 このIDの違いがどのような効果をもたらすのかについては、もう少し後で見てみることにしましょう。

この連載の記事
ASCII倶楽部にて、週刊アスキーの人気ルポ漫画『カオスだもんね!PLUS』が、まとめて読める新コンテンツがついに配信開始!

週間ランキングTOP5

ASCII倶楽部会員によく見られてる記事はコレだ!

ASCII倶楽部の新着記事

会員専用動画の紹介も!