【Swift】Date構造体の使い方!日付の計算や比較方法

この記事からわかること
- SwiftのDate構造体の使い方
- 日付の差分や加算、減算などの計算方法
- UTCによる9時間のズレ
- 比較演算子を用いた比較
index
[open]
\ アプリをリリースしました /
参考文献: API Collection Dates and Times
Swiftの日付や時間操作API
Swiftでは日付や時間などを操作、管理するためにいくつかの構造体やクラスが基礎となるFoundationフレークワークの中に用意されています。
役割やできること
・Date構造体
・・・特定の日時を表す(カレンダーやタイムゾーンと無関係)
・DateInterval構造体
・・・期間
・TimeIntervalタイプエイリアス
・・・秒数(Double型のエイリアス)
・DateComponents構造体
・・・日付情報の一部を取得できる
・Calendar構造体
・・・日付の比較や計算や書き換えなどが可能
・TimeZone構造体
・・・日付情報のタイムゾーンを表す
・DateFormatterクラス
・・・日付情報を任意のフォーマットで表示
ざっくり見ると上記の通りです。それぞれ日時に関する機能を提供するAPIですが細かい役割が異なります。またこれらは密接に関わりを持っているので相互の変換などを行うことも可能です。
おすすめ記事
【Swift UI】typealias(タイプエイリアス)の使い方とメリット
【Swift】DateFormatterの使い方!書式や日付形式の調整方法
【Swift】DateComponentsとは?使用方法とDate型との違い
【Swift】Calendar構造体の使い方!暦法の変更と日付の計算
Date構造体とは?
Date
構造体とは設定されているカレンダーやタイムゾーンとは関連を持たず、特定の日時を表現するオブジェクトです。引数なしのイニシャライザまたはタイププロパティ(static)nowから現在時刻のインスタンスを生成(参照)することができます。
おすすめ記事:【Swift】プロパティの種類!ストアドプロパティやタイププロパティとは?
9時間のズレが生じる原因
しかしprint
した時刻とオブジェクトの時刻では10時とPM 7時(19時)で日時情報には誤差が生まれています。これはDateオブジェクトがUTC(協定世界時)で日時情報を保持しているためであり、UTCと日本標準時(JTC)とは9時間ズレているため誤差が生まれてしまうのです。
playgroundで見た時に+0000
となるのは誤差が0時間(つまりUTC)であることを表しています。
日本標準時で文字列として出力したい場合はdescription(with:)
メソッドの引数に任意のロケール値を渡せば出力可能です。
またDateFormatter
クラスを使用した方法でも出力できます。
任意の時間後のオブジェクトを生成する
現在時刻のオブジェクトの生成方法が分かったところで30秒後や2日後、1年後など任意の時間経過後のオブジェクトを生成する方法をみていきます。
実装するにはinit(timeIntervalSinceNow:)
を使用します。引数にはTimeInterval
型(Doubleのエイリアス)で現在から任意の日時までの秒数を渡します。
その他のプロパティやメソッド
timeIntervalSince1970:UNIX形式で取得
timeIntervalSince1970
プロパティは自身の日付と1970年1月1日の00:00:00 UTCとの間隔(UNIX)をTimeInterval型の秒数で取得できます。
TimeInterval
はDouble
のタイプエイリアスとなっています。またTimeInterval
型は簡単にDate
型に変換できるようになっています。
日付の比較
DateオブジェクトはComparable
プロトコルに準拠しているため演算子(=><)を用いた比較が可能になっています。
上記の場合は一致になりそうですが、インスタンス化のタイミングにわずかながら誤差がある(秒数がズレる)ため不一致になるのでしょうか。もちろん同じインスタンス同士は一致し、比較してみるとday2
の方が大きい(時間が進んでいる)となるようです。
Calendar.isDate(_:inSameDayAs:)で日付の一致を識別
公式リファレンス:isDate(_:inSameDayAs:)
日付が一致するかどうかを識別するためにはCalendar
構造体のisDate(_:inSameDayAs:)
を使用することもできます。
日付の計算方法
任意の日付から加算や減算などDate型のまま計算をするにはCalendar.date(byAdding:,value: ,to:)
メソッドを使用します。Calendar
からは他にも日付を操作するための様々なメソッドが用意されています。
おすすめ記事:【Swift】日付が期間内か識別する方法!switch文で範囲の定義
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。