Q:

How to output a date range for each quarter of a year in Ruby?

Thanks to some people on this board I was able to come up with a function that returns a number of date ranges:
years = [2013, 2012, 2011, 2010, 2009]

def month_ranges
  years.flat_map { |y|
    12.downto(1).map { |m| Date.new(y,m,1)..Date.new(y,m,-1) }
  }
end

# => 

[
  01 Dec 2013..31 Dec 2013, 
  01 Nov 2013..31 Nov 2013, 
  01 Oct 2013..31 Oct 2013, 
  01 Sep 2013..31 Sep 2013,
  01 Aug 2013..31 Aug 2013,
  ....
]

Now, is there a way to return the four quarters of a year as well?
So the output will be something like:
# => 

[
  01 Oct 2013..31 Dec 2013,
  01 Jul 2013..31 Sep 2013,
  01 Apr 2013..31 Jun 2013,
  01 Jan 2013..31 Mar 2013
]

(Note: If a month has 30 or 31 days doesn't really matter in this case.)
Thanks to anyone who can help.

A:

This should work (based on month_ranges, i.e. last quarter comes first):
def quarter_ranges
  years.flat_map { |y|
    3.downto(0).map { |q|
      Date.new(y, q * 3 + 1, 1)..Date.new(y, q * 3 + 3, -1)
    }
  }
end

Or a bit more verbose and maybe easier to understand:
def quarter_ranges
  years.flat_map { |y|
    [
      Date.new(y, 10, 1)..Date.new(y, 12, -1),
      Date.new(y,  7, 1)..Date.new(y,  9, -1),
      Date.new(y,  4, 1)..Date.new(y,  6, -1),
      Date.new(y,  1, 1)..Date.new(y,  3, -1)
    ]
  }
end

A:

You can use beginning_of_quarter and end_of_quarter to define quarters.
For example, if I want to group a date_range according to quarters I could do the following:
((Date.today - 1.year)..Date.today).group_by(&:beginning_of_quarter)

The keys in this case are the beginning of each quarter:
((Date.today - 1.year)..Date.today).group_by(&:beginning_of_quarter).keys
=> [Sun, 01 Jul 2012, Mon, 01 Oct 2012, Tue, 01 Jan 2013, Mon, 01 Apr 2013, Mon, 01 Jul 2013]

