この記事では、SwiftUIでのDate型やCalendarクラスを利用する日付の計算、比較の方法を紹介しています。
日付、時刻の比較
例としてDate() で取得できる日付(実行時に今日の現時刻)と、Date() で取得できる日付の3日前の日付の比較を行います。
Date型の日付データの比較
今日より3日前の日付データの作成
以下のコードで、今日と3日前のDate 型の値を作ります。
1 2 3 4 5 6 7 | let today = Date() let day3DaysAgo = Calendar.current.date(byAdding: .day, value: -3, to: today)! print("day3DaysAgo:\(day3DaysAgo!)") //day3DaysAgo:2021-03-05 02:44:45 +0000 print("today:\(today)") //today:2021-03-08 02:44:45 +0000 |
これで比較する事ができます。
1 2 3 4 5 | print(today == day3DaysAgo) //false print(today < day3DaysAgo) //false print(today > day3DaysAgo) //true |
DateComponents型の日付データの比較
DateComponents型のデータで比較する事で、年、月、日など(時刻を比較しない)の条件で比較する処理が行いやすくなります。
まずは、先程作成したDate型のデータを素にDateComponents型の日付データを作成します。
1 2 3 4 5 6 7 8 9 10 11 | let today = Date() let day3DaysAgo = Calendar.current.date(byAdding: .day, value: -3, to: today)! let todayDC = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: today) let day3DaysAgoDC = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: day3DaysAgo) print("todayDC:\(todayDC)") //todayDC:year: 2021 month: 3 day: 8 hour: 10 minute: 8 isLeapMonth: false print("day3DaysAgoDC:\(day3DaysAgoDC)") //day3DaysAgoDC:year: 2021 month: 3 day: 5 hour: 10 minute: 8 isLeapMonth: false |
この状態で2つのデータを比較すると、違う値となります。
1 2 3 | print(todayDC == day3DaysAgoDC) //false |
そこで、DateComponents型のデータを作る際に、年月のみの値として比較してみます。
1 2 3 4 5 6 7 8 9 | let todayDC = Calendar.current.dateComponents([.year, .month], from: today) let day3DaysAgoDC = Calendar.current.dateComponents([.year, .month], from: day3DaysAgo) print("todayDC:\(todayDC)") //todayDC:year: 2021 month: 3 isLeapMonth: false print("day3DaysAgoDC:\(day3DaysAgoDC)") //day3DaysAgoDC:year: 2021 month: 3 isLeapMonth: false print(todayDC == day3DaysAgoDC) //true |
このようにする事で、それぞれの日付データの年と月の値で比較するので、同じ値として比較されるようになります。
比較の条件に時間を含めずに、年月日を利用する時などで利用できます。
年月日、時刻の値を指定して比較する。
これまでは、Date型の値からDateComponents型の値を作成していました。
ここでは、DateComponents型で日付、時刻を指定して値を作る方法を紹介します。
例として2021年3月1日0時0分の値を作ります。
1 2 3 4 5 6 | let calendar = Calendar(identifier: .gregorian) let day1stOfMarch2021 = calendar.date(from: DateComponents(year: 2021, month: 3, day: 1, hour: 9, minute: 0)) print(day1stOfMarch2021) //Optional(2021-03-01 00:00:00 +0000) |
この場合、Calendarクラスのグレゴリオ暦を指定したインスタンスを作り、年月日、時刻を指定しています。
素の時間はグレゴリオ暦となるため、日本で実行する際は7時とする事で、0時00分を表示する事ができます。
しかし、この方法の場合は作成した値はDate型となります。
さきほど、作成したDateComponents型の値と比較するには、型を同じにする必要があります。
今回は、Date型に共通させ、値を比較します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let calendar = Calendar(identifier: .gregorian) let day1stOfMarch2021 = calendar.date(from: DateComponents(year: 2021, month: 3, day: 1, hour: 7, minute: 0)) let todayDC = Calendar.current.dateComponents([.year, .month, .day], from: today) let todayDate = calendar.date(from: DateComponents(year: todayDC.year, month: todayDC.month, day: todayDC.day, hour: 7, minute: 0)) print("todayDC:\(day1stOfMarch2021!)") //todayDC:2021-03-01 00:00:00 +0000 print("todayDate:\(todayDate!)") //todayDate:2021-03-08 00:00:00 +0000 print(day1stOfMarch2021! == todayDate!) //false print(day1stOfMarch2021! < todayDate!) //true print(day1stOfMarch2021! > todayDate!) //false |
String型の日付データの比較
DateComponents型のデータでの比較同夜に、String型を利用する事で、年、月、日など(時刻を比較しない)の条件で比較する処理が行いやすくなります。
Date型の値をDateFormatter クラスを利用してString型に変更し比較します。
以下のコードにする事で、年月日の値で2のデータを比較しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | let date1 = Date() let date2 = Date() func dateFormatYMD(date: Date) -> String { let df = DateFormatter() df.dateStyle = .long df.timeStyle = .none return df.string(from: date) } print(dateFormatYMD(date:date1) == dateFormatYMD(date:date2)) //true print(dateFormatYMD(date:date1) < dateFormatYMD(date:date2)) //false print(dateFormatYMD(date:date1) > dateFormatYMD(date:date2)) //false |
日付、時刻の計算
次に日付、時刻の計算の方法を解説します。
ここでは、さきほど作成したDate型の3月1日と3月8日の差分となる7日(7)を取得してみたいと思います。
1 2 3 4 | let calendar = Calendar(identifier: .gregorian) calendar.dateComponents([.day], from:Date(), to: Date()).day |
を利用してコードを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | let calendar = Calendar(identifier: .gregorian) let day1stOfMarch2021 = calendar.date(from: DateComponents(year: 2021, month: 3, day: 1, hour: 7, minute: 0)) let today = Date() let todayDC = Calendar.current.dateComponents([.year, .month, .day], from: today) let todayDate = calendar.date(from: DateComponents(year: todayDC.year, month: todayDC.month, day: todayDC.day, hour: 7, minute: 0)) let progressDays = calendar.dateComponents([.day], from: day1stOfMarch2021!, to: todayDate!).day print("day1stOfMarch2021:\(day1stOfMarch2021!)") //day1stOfMarch2021:2021-03-01 00:00:00 +0000 print("todayDate:\(todayDate!)") //todayDate:2021-03-08 00:00:00 +0000 print(progressDays!) //7 |
以上、SwiftUIでのDate型やCalendarクラスを利用する日付の計算、比較の方法を紹介しました。