Der folgende Ansatz betont die Effizienz über die Kürze, indem die Notwendigkeit vermieden wird, zu bestimmen, ob jeder Tag in einem Bereich ein bestimmter Tag (oder einer von zwei vorgegebenen Tagen) der Woche ist.
-Code
require 'date'
def dates_by_years_and_wday(start_year, end_year, wday)
(first_date_by_year_and_wday(start_year, wday)...
first_date_by_year_and_wday(end_year+1, wday)).step(7).to_a
end
def first_date_by_year_and_wday(year, wday)
d = Date.new(year)
d + (wday >= d.wday ? wday - d.wday : 7 + wday - d.wday)
end
Beachten Sie, dass der Bereich mit den drei Punkten definiert ist, wird das erste Datum Bedeutung in end_year
ausgeschlossen.
Beispiel
SATURDAY = 6
SUNDAY = 0
start_year, end_year = 2015, 2017
dates_by_years_and_wday(start_year, end_year, SATURDAY)
#=> [#<Date: 2015-01-03 ((2457026j,0s,0n),+0s,2299161j)>,
# #<Date: 2015-01-10 ((2457033j,0s,0n),+0s,2299161j)>,
# ...
# #<Date: 2017-12-30 ((2458118j,0s,0n),+0s,2299161j)>]
dates_by_years_and_wday(start_year, end_year, SATURDAY).size
#=> 157
dates_by_years_and_wday(start_year, end_year, SUNDAY)
#=> [#<Date: 2015-01-04 ((2457027j,0s,0n),+0s,2299161j)>,
# #<Date: 2015-01-11 ((2457034j,0s,0n),+0s,2299161j)>,
# ...
# #<Date: 2017-12-31 ((2458119j,0s,0n),+0s,2299161j)>]
dates_by_years_and_wday(start_year, end_year, SUNDAY).size
#=> 157