TL;DR
# 2022-10-11 ~ 2022-12-13 の間、火曜日の個数を計算する
require 'date' # Rails環境では不要
(Date.parse('2022-10-11')..Date.parse('2022-12-13')).select(&:tuesday?).size
# または
(Date.parse('2022-10-11')..Date.parse('2022-12-13')).select{ |d| d.wday == 2 }.size
=> 10
はじめて
最近はイタリア語講座に参加しました、案内ではこう書いていました。
曜日・時間: 火曜日 19:30 ~ 21:00
受講期間: 2022-10-11 ~ 2022-12-13
授業回数: 10回
しかし私は途中参加なので、果たして案内に書かれた期間に10回の授業が完了できるのか?また、休講があるのか?を懸念していました。
私は算数があんまり得意ではないので、カレンダーで数えてみましたが、なかなか正確な結果出ませんでした。
そこで、Rubyのチカラを借りたいと考えました。
解説
Rails環境で解説いたしますが、純Rubyの環境では require 'date'
でライブラリーを導入すれば同じ結果になります。
日付の区間の取得
始まりの日付と終わりの日付を、..
で範囲オブジェクトを作ります。
(Date.parse('2022-10-11')..Date.parse('2022-12-13'))
=> Tue, 11 Oct 2022..Tue, 13 Dec 2022
範囲オブジェクトは一種のイテレーター(iterator)であり、配列と同じように、.each
や.map
とかが使えます。ただし、イテレーションを行うまでは展開しません。
どうしても展開したい(配列として扱いたい)場合は、.to_a
で配列に転換することもできます。
(Date.parse('2022-10-11')..Date.parse('2022-12-13')).to_a
# または
[*(Date.parse('2022-10-11')..Date.parse('2022-12-13'))]
=> [Tue, 11 Oct 2022,
Wed, 12 Oct 2022,
Thu, 13 Oct 2022,
Fri, 14 Oct 2022,
...
所定の曜日のピックアップ
RubyのDate Classは、インスタンスメソッドで .monday?
〜 .sunday?
が実装されています。所定曜日のメソッドを使うか、.wday
で数字化した曜日を算出して比較します。
(Date.parse('2022-10-11')..Date.parse('2022-12-13')).select(&:tuesday?)
# または
(Date.parse('2022-10-11')..Date.parse('2022-12-13')).select{ |d| d.wday == 2 }
=> [Tue, 11 Oct 2022, Tue, 18 Oct 2022, Tue, 25 Oct 2022, Tue, 01 Nov 2022, Tue, 08 Nov 2022, Tue, 15 Nov 2022, Tue, 22 Nov 2022, Tue, 29 Nov 2022, Tue, 06 Dec 2022, Tue, 13 Dec 2022]
これで、.size
をつけば、2022-10-11~2022-12-13の間火曜日は10個あることがわかります。
.wday
と.cwday
の仕様
余談ですが、RubyのDateオブジェクトの曜日番号を取得するには、.wday
と.cwday
2つのメソッドがあります。その違いは以下になります。
-
.wday
は日曜日をから、0~6の数字で表示します(0は日曜日) -
.cwday
は月曜日をから、1~7の数字で表示します(7は日曜日)