自分用の覚書
Railsではいろいろと便利な日付計算用のメソッドが用意されている。
その中でもnext_week
とかprev_week
とかの、いかにも「来週(7日後)/先週(7日前)の日付を取得する」ように見えるメソッドがある
しかし実際にやってみると、ちょっと感覚とズレていた
[1] pry(main)> date = Date.new(2025,6,1)
=> Sun, 01 Jun 2025
[2] pry(main)> date.next_week
=> Mon, 02 Jun 2025
来週の日曜日、つまり6月8日(Sun, 08 Jun 2025)が返ってくることを想定していたのに、実際には翌日の値が返ってきてしまった
これはRailsの初期値ではbeginning_of_week
が:monday
に設定されており、next_week
の引数はこの値をデフォルトで受け取っている
この際のweekが「月曜日から始まり日曜日に終わる」という「週間」の意味になっており
5/26(月) 〜 6/1(日)
6/2(月) 〜 6/8(日)
6/9(月) 〜 6/16(日)
といった形での捉え方がされているようだ
そのため6/1の「来週間」は、6/2 〜 6/8 となる
次のようにしてみると分かりやすい
[1] pry(main)> ("2025-05-25".to_date .. "2025-06-02".to_date).each do |date|
[1] pry(main)> puts "#{date} => #{date.next_week}"
[1] pry(main)> end
2025-05-25 => 2025-05-26
2025-05-26 => 2025-06-02
2025-05-27 => 2025-06-02
2025-05-28 => 2025-06-02
2025-05-29 => 2025-06-02
2025-05-30 => 2025-06-02
2025-05-31 => 2025-06-02
2025-06-01 => 2025-06-02
2025-06-02 => 2025-06-09
next_week
は、来週間の始まりの日付を返すだけであって、来週の同じ曜日の日付を返すわけではない
引数に:sunday
を渡してやったり、config.beginning_of_week
を変更したりすれば、基準となる曜日が変わりはするが、本質的には変わらない
来週/先週の日付が欲しい場合
この場合は、大人しくweeks_since
weeks_ago
や1.weeks
7.days
とかをつかって計算しよう
[1] pry(main)> Date.new(2025,6,1).weeks_since(1)
=> Sun, 08 Jun 2025
[2] pry(main)> Date.new(2025,6,1) + 1.weeks
=> Sun, 08 Jun 2025
[3] pry(main)> Date.new(2025,6,1).weeks_ago(1)
=> Sun, 25 May 2025
[4] pry(main)> Date.new(2025,6,1) - 1.weeks
=> Sun, 25 May 2025
次の◯曜日/前の◯曜日 が欲しい場合
参考
[1] pry(main)> Date.new(2025,6,1).next_occurring(:monday)
=> Mon, 02 Jun 2025
[2] pry(main)> Date.new(2025,6,1).next_occurring(:sunday)
=> Sun, 08 Jun 2025
[3] pry(main)> Date.new(2025,6,1).prev_occurring(:monday)
=> Mon, 26 May 2025
[4] pry(main)> Date.new(2025,6,1).prev_occurring(:sunday)
=> Sun, 25 May 2025
余談
じゃあDateクラス由来のnext_month
/prev_month
、 next_year
/prev_year
は? というと
[1] pry(main)> Date.new(2025,6,1).next_month
=> Tue, 01 Jul 2025
[2] pry(main)> Date.new(2025,6,1).prev_month
=> Thu, 01 May 2025
[3] pry(main)> Date.new(2025,6,1).next_year
=> Mon, 01 Jun 2026
[4] pry(main)> Date.new(2025,6,1).prev_year
=> Sat, 01 Jun 2024
うるう年も問題なさそう
[1] pry(main)> Date.new(2024,2,29).next_year
=> Fri, 28 Feb 2025
[2] pry(main)> Date.new(2024,2,29).next_year(4)
=> Tue, 29 Feb 2028
[3] pry(main)> Date.new(2024,2,29).prev_year
=> Tue, 28 Feb 2023
[4] pry(main)> Date.new(2024,2,29).prev_year(4)
=> Sat, 29 Feb 2020
DateAndTime::Calculationsのnext_week
/prev_week
の命名が悪いのでは……?