Swift の Calendar で 31 日が存在する月などを取得する方法

 例えば、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 を指定すれば、うるう年を取得できます。

この記事をシェア
  • このエントリーをはてなブックマークに追加
  • Share on Google+
  • この記事についてツイート
  • この記事を Facebook でシェア