NSCalendarでSwiftの日付操作

エンジニアの渡辺です。 前回ブログの続きです。 今回はNSCalendarでの日付の差分や比較方法、 その他デ…

エンジニアの渡辺です。

前回ブログの続きです。
今回はNSCalendarでの日付の差分や比較方法、
その他データの取得方法などを書いていきたいと思います。
>> 前回ブログ

■はじめに


比較用のデータを作成していきます。
今回は、2017/08/01 10:30と2017/09/25 13:30で比較して行きます。

// 西暦を設定
let calendar = NSCalendar(identifier: .gregorian)

// 日付を指定してDate(2017/08/01 10:30)を作成
let fromDate = calendar?.date(era: 1, year: 2017, month: 8,
                              day: 1, hour: 10, minute: 30,
                              second: 0, nanosecond: 0)

// 日付を指定してDate(2017/09/25 13:30)を作成
let toDate = calendar?.date(era: 1, year: 2017, month: 9,
                            day: 25, hour: 13, minute: 30,
                            second: 0, nanosecond: 0)

出力結果は以下の様になります。

fromDate: 2017/08/01 10:30
toDate: 2017/09/25 13:30

■二つの日時の差分を求める


用意した二つの日付の差分を全ての要素と日数で求めます。

// 二つの日時の差分を求める
// すべて比較
let diffAll = calendar?.components([.year, .month, .day, .hour, .minute],
                                    from: fromDate!, to: toDate!,
                                    options: .matchLast)

// 日数で比較
let diffDay = calendar?.components([.day], from: fromDate!, to: toDate!,
                                   options: .matchLast)

出力結果は以下の様になります。

すべて比較
Year: 0
Month: 1
Day: 24
Hour: 3
Minute: 0
日数で比較
Day: 55

■二つの日時を比較


二つの日時の一致を比較します。

// 二つの日時を比較する
// 年月日の比較
if (calendar?.isDate(fromDate!, inSameDayAs: toDate!))!
{
    print("年月日が一致")
}
else
{
    print("年月日が不一致")
}

// 年の比較
if (calendar?.isDate(fromDate!, equalTo: toDate!,
                     toUnitGranularity: .year))!
{
    print("年が一致")
}
else
{
    print("年が不一致")
}

// 全く同じ日時か比較
if fromDate == toDate
{
    print("日時が一致")
}
else
{
    print("日時が不一致")
}

// 日付が今日か
if (calendar?.isDateInToday(toDate!))!
{
    print("今日の日付と一致")
}
else
{
    print("今日の日付と不一致")
}

// 日付が昨日か
if (calendar?.isDateInYesterday(toDate!))!
{
    print("昨日の日付と一致")
}
else
{
    print("昨日の日付と不一致")
}

// 日付が明日か
if (calendar?.isDateInTomorrow(toDate!))!
{
    print("明日の日付と一致")
}
else
{
    print("明日の日付と不一致")
}

// 日付が週末か
if (calendar?.isDateInWeekend(toDate!))!
{
    print("日付は週末です")
}
else
{
    print("日付は週末ではありません")
}

出力結果は以下の様になります。

年月日が不一致
年が一致
日時が不一致
今日の日付と一致
昨日の日付と不一致
明日の日付と不一致
日付は週末ではありません

■曜日関連


曜日関連のメソッドを試してみます。

// 曜日関連
// 曜日を取得する
let toDateWeekday = calendar?.component(.weekday, from: toDate!)

// 曜日の配列を取得
let weekdaySymbols = calendar?.weekdaySymbols

// カレンダーのロケーションを日本に設定
calendar?.locale = Locale.init(identifier: "ja")
let japanWeedaySymbols = calendar?.weekdaySymbols

出力結果は以下の様になります。

曜日: 2
曜日一覧(英語): ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
曜日一覧(日本語) ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]

2017/09/25は月曜日なのですが、配列でそのまま指定すると火曜日が返ってきてしまいます。
どうせなら曜日一覧と曜日のインデックスを合わせてくれれば配列からそのまま要素を取れるのに。。
と思いながら色々試して見ました。

// 日曜日のデータを作成(2017/09/24)
let sundayDate = calendar?.date(era: 1, year: 2017, month: 9,
                                day: 24, hour: 13, minute: 30,
                                second: 0, nanosecond: 0)

// 日曜日の曜日インデックスを取得する
let sundayDateWeekday = calendar?.component(.weekday, from: sundayDate!)

// 土曜日のデータを作成(2017/09/23)
let saturdayDate = calendar?.date(era: 1, year: 2017, month: 9,
                                  day: 23, hour: 13, minute: 30,
                                  second: 0, nanosecond: 0)

// 土曜日の曜日インデックスを取得する
let saturdayDateWeekday = calendar?.component(.weekday, from: saturdayDate!)

出力結果は以下の様になります。

日曜日のデータの曜日インデックス: 1
土曜日のデータの曜日インデックス: 7

曜日配列からその日の曜日を取得する場合は取得した曜日のインデックス-1した要素を取ればよさそうです。

let toDateWeekdaySymbol = japanWeedaySymbols![toDateWeekday! - 1]
let sundayDateWeekdaySymbol = japanWeedaySymbols![sundayDateWeekday! - 1]
let saturdayDateWeekdaySymbol = japanWeedaySymbols![saturdayDateWeekday! - 1]

出力結果は以下の様になります。

2017/09/25の曜日: 月曜日
2017/09/24の曜日: 日曜日
2017/09/23の曜日: 土曜日

正しい曜日が取得できました。


日付の操作はスケジュールアプリ作成時以外にも使うことが多いと思うので、
何かの際に役に立てば幸いです。