例えば、31 日が存在する月だけを取得、のようなことを、Swift 3 の Calendar で行う方法です。
あまり遭遇しないケースかと思いますが、どなたかのお役に立ちましたら。
スポンサーリンク
読み込み中です。少々お待ち下さい
方法その1
Calendar.enumerateDates を使用して、matchingPolicy の day に 31 を指定することにより取得できます。
説明の都合上、まずは少し回りくどい方法をとってみましょう。
let cal = Calendar.current
let dateFormatter = DateFormatter()
dateFormatter.calendar = cal
dateFormatter.dateStyle = .medium
guard let feb2017 = cal.date(from: DateComponents(year: 2017, month: 2, day: 1)) else { return }
cal.enumerateDates(startingAfter: feb2017, matching: DateComponents(day: 31), matchingPolicy: .nextTime) { (date: Date?, isExact: Bool, stop: inout Bool) in
guard let date = date else { stop = true; return }
print("\(dateFormatter.string(from: date)) - \(isExact)")
stop = isExact // stop = true で列挙終了
}
出力結果
2017/03/01 - false
2017/03/31 - true
2017/02/01 から開始していますので、初回は 2017/02/31 ということになります。
だたし、2017/02/31 という年月日は存在しませんから、この場合は翌月の 1 日が date に設定されます。
この時、isExact には false が設定されますので、isExact = true の場合が 31 日の存在する月だと判断できます(31 日が存在する 3 月は isExact = true であることが、サンプルの出力結果で確認できます)。
方法その2
方法その1を踏まえて、matchingPolicy を変更しつつ、ざっくり 1 年ほど先まで 31 日が存在する月を列挙してみましょう。
let cal = Calendar.current
let dateFormatter = DateFormatter()
dateFormatter.calendar = cal
dateFormatter.dateStyle = .medium
guard let feb2017 = cal.date(from: DateComponents(year: 2017, month: 2, day: 1)) else { return }
guard let feb2018 = cal.date(byAdding: .year, value: 1, to: feb2017) else { return }
cal.enumerateDates(startingAfter: feb2017, matching: DateComponents(day: 31), matchingPolicy: .strict) { (date: Date?, isExact: Bool, stop: inout Bool) in
guard let date = date else { stop = true; return }
print("\(dateFormatter.string(from: date)) - \(isExact)")
stop = feb2018 < date // stop = true で列挙終了
}
出力結果
2017/03/31 - true
2017/05/31 - true
2017/07/31 - true
2017/08/31 - true
2017/10/31 - true
2017/12/31 - true
2018/01/31 - true
2018/03/31 - true
matchingPolicy に strict を指定することにより、matching に正確に一致する date のみ列挙できます。
Calendar.enumerateDates では、他に方向(direction)等も指定できますので、目的に合わせて使い分けましょう。
おわりに
他にも、例えば matching に 2 月 29 日、matchingPolicy に strict を指定すれば、うるう年を取得できます。