from = Date.parse('15.01.2016')
to = Date.parse('10.06.2016')
(from..to).group_by(&:month).map do |group|
group.last.first.beginning_of_month..group.last.last.end_of_month
end
# => [Fri, 01 Jan 2016..Sun, 31 Jan 2016,
# Mon, 01 Feb 2016..Mon, 29 Feb 2016,
# Tue, 01 Mar 2016..Thu, 31 Mar 2016,
# Fri, 01 Apr 2016..Sat, 30 Apr 2016,
# Sun, 01 May 2016..Tue, 31 May 2016,
# Wed, 01 Jun 2016..Thu, 30 Jun 2016]
Or, map dates to strings, if you need string representation:
(from..to).group_by(&:month).map do |group|
"#{group.last.first.beginning_of_month} - #{group.last.last.end_of_month}"
end
# => ["2016-01-01 - 2016-01-31",
# "2016-02-01 - 2016-02-29",
# "2016-03-01 - 2016-03-31",
# "2016-04-01 - 2016-04-30",
# "2016-05-01 - 2016-05-31",
# "2016-06-01 - 2016-06-30"]
To get precisely what you want, you can format the string representation of the dates:
(from..to).group_by(&:month).map do |group|
"#{group.last.first.beginning_of_month.strftime('%d-%m-%Y')} - #{group.last.last.end_of_month.strftime('%d-%m-%Y')}"
end
#=> ["01-01-2016 - 31-01-2016",
# "01-02-2016 - 29-02-2016",
# "01-03-2016 - 31-03-2016",
# "01-04-2016 - 30-04-2016",
# "01-05-2016 - 31-05-2016",
# "01-06-2016 - 30-06-2016"]
EDIT
To make sure ranges do not mix up because of different years, include it in grouping along with month:
from = Date.parse('15.01.2016')
to = Date.parse('10.02.2017')
(from..to).group_by {|a| [a.year, a.month]}.map do |group|
"#{group.last.first.beginning_of_month.strftime('%d-%m-%Y')} - #{group.last.last.end_of_month.strftime('%d-%m-%Y')}"
end
# => ["01-01-2016 - 31-01-2016",
# "01-02-2016 - 29-02-2016",
# "01-03-2016 - 31-03-2016",
# "01-04-2016 - 30-04-2016",
# "01-05-2016 - 31-05-2016",
# "01-06-2016 - 30-06-2016",
# "01-07-2016 - 31-07-2016",
# "01-08-2016 - 31-08-2016",
# "01-09-2016 - 30-09-2016",
# "01-10-2016 - 31-10-2016",
# "01-11-2016 - 30-11-2016",
# "01-12-2016 - 31-12-2016",
# "01-01-2017 - 31-01-2017",
# "01-02-2017 - 28-02-2017"]