Одна вещь, которую вы можете сделать, это превратить каждую дату в «номер месяца» это год, умноженная на 12 плюс нуля месяц, а затем перебрать их, например:
from_date = Date.new(2015, 11) # Nov. 1, 2015
to_date = Date.today # Mar. 22, 2016
nov2015 = from_date.year * 12 + (from_date.month - 1)
# => 24190
nov2015.divmod(12)
# => [2015, 10]
mar2016 = to_date.year * 12 + (to_date.month - 1)
# => 24194
mar2016.divmod(12)
# => [2016, 2]
Помните, что месяцы равны нулю, поэтому 2
- март, а 10
- ноябрь. Как и ожидалось, nov2015
и mar2016
имеют разницу в четыре. Теперь мы можем перебирать один из другого:
nov2015.upto(mar2016) do |month_num|
year, month = month_num.divmod(12)
puts Date.new(year, month + 1).strftime("%B %Y")
end
# => November 2015
# December 2015
# January 2016
# February 2016
# March 2016
Отлично! Но это лучше, если мы можем поставить это в метод, который возвращает нумератор, поэтому мы можем использовать любой из перечислимых методов (each
, map
, each_cons
, вы называете его) на нем:
def months_enum(from_date, to_date)
from = from_date.year * 12 + from_date.month - 1
to = to_date.year * 12 + to_date.month - 1
Enumerator.new do |y|
from.upto(to) do |n|
year, month = n.divmod(12)
y << Date.new(year, month + 1)
end
end
end
Тогда:
from = Date.new(2015, 11, 1)
to = Date.today
months_enum(from, to).each do |date|
puts date.strftime("%Y-%m")
end
# -> 2015-11
# 2015-12
# 2016-01
# 2016-02
# 2016-03
p months_enum(from, to).map {|date| date.strftime("%B %Y") }
# => [ "November 2015",
# "December 2015",
# "January 2016",
# "February 2016",
# "March 2016" ]
Сколько лет и месяцев вы хотите пройти? Вы можете добавить числа, такие как 1.month, чтобы медленно увеличиваться в течение месяцев – Vincent