```ruby
require 'date'
class Date
def quarter
case month
when 1, 2, 3 then 1
when 4, 5, 6 then 2
when 7, 8, 9 then 3
when 10, 11, 12 then 4
end
end
def start_of_previous_quarter
end_of_previous_quarter.start_of_quarter
end
def previous_quarter
start_of_quarter.prev_day
end
def next_quarter
end_of_quarter.next_day.end_of_quarter
end
def start_of_quarter
first_month = quarter * 3 - 2
Date.new(year, first_month, 1)
end
def end_of_quarter
last_month = quarter * 3
Date.new(year, last_month, 1).next_month.prev_day
end
def quarters_between(other_date)
current = self
quarters = [current.end_of_quarter]
while current < other_date
current = current.advance(months: 3).end_of_quarter
quarters << current
end
quarters
end
end
```
Example:
```ruby
class DateTest < ActiveSupport::TestCase
test "quarter" do
assert_equal 1, Date.new(2020, 3, 1).quarter
assert_equal 1, Date.new(2020, 3, 31).quarter
assert_equal 2, Date.new(2020, 4, 1).quarter
assert_equal 2, Date.new(2020, 6, 30).quarter
assert_equal 3, Date.new(2020, 7, 1).quarter
assert_equal 3, Date.new(2020, 9, 30).quarter
assert_equal 4, Date.new(2020, 10, 1).quarter
assert_equal 4, Date.new(2020, 12, 31).quarter
end
test "start_of_quarter" do
assert_equal Date.new(2020, 1, 1), Date.new(2020, 3, 1).start_of_quarter
assert_equal Date.new(2020, 1, 1), Date.new(2020, 3, 31).start_of_quarter
assert_equal Date.new(2020, 4, 1), Date.new(2020, 4, 1).start_of_quarter
assert_equal Date.new(2020, 4, 1), Date.new(2020, 6, 30).start_of_quarter
assert_equal Date.new(2020, 7, 1), Date.new(2020, 7, 1).start_of_quarter
assert_equal Date.new(2020, 7, 1), Date.new(2020, 9, 30).start_of_quarter
assert_equal Date.new(2020, 10, 1), Date.new(2020, 12, 1).start_of_quarter
assert_equal Date.new(2020, 10, 1), Date.new(2020, 12, 31).start_of_quarter
end
test "end_of_quarter" do
assert_equal Date.new(2020, 3, 31), Date.new(2020, 1, 1).end_of_quarter
assert_equal Date.new(2020, 3, 31), Date.new(2020, 3, 31).end_of_quarter
assert_equal Date.new(2020, 6, 30), Date.new(2020, 4, 1).end_of_quarter
assert_equal Date.new(2020, 6, 30), Date.new(2020, 6, 30).end_of_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 7, 1).end_of_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 9, 30).end_of_quarter
assert_equal Date.new(2020, 12, 31), Date.new(2020, 10, 1).end_of_quarter
assert_equal Date.new(2020, 12, 31), Date.new(2020, 12, 31).end_of_quarter
end
test "next_quarter" do
assert_equal Date.new(2020, 6, 30), Date.new(2020, 1, 1).next_quarter
assert_equal Date.new(2020, 6, 30), Date.new(2020, 3, 31).next_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 4, 1).next_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 6, 30).next_quarter
assert_equal Date.new(2020, 12, 31), Date.new(2020, 9, 30).next_quarter
assert_equal Date.new(2021, 3, 31), Date.new(2020, 10, 1).next_quarter
assert_equal Date.new(2021, 3, 31), Date.new(2020, 12, 31).next_quarter
end
test "prev_quarter" do
assert_equal Date.new(2019, 12, 31), Date.new(2020, 1, 1).previous_quarter
assert_equal Date.new(2019, 12, 31), Date.new(2020, 3, 31).previous_quarter
assert_equal Date.new(2020, 3, 31), Date.new(2020, 4, 1).previous_quarter
assert_equal Date.new(2020, 3, 31), Date.new(2020, 6, 30).previous_quarter
assert_equal Date.new(2020, 6, 30), Date.new(2020, 7, 1).previous_quarter
assert_equal Date.new(2020, 6, 30), Date.new(2020, 9, 30).previous_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 10, 1).previous_quarter
assert_equal Date.new(2020, 9, 30), Date.new(2020, 12, 31).previous_quarter
end
test "quarters_between" do
qtrs = Date.new(2019, 1, 1).quarters_between(Date.new(2020, 1, 1))
assert_equal [ Date.new(2019, 3, 31), Date.new(2019, 6, 30), Date.new(2019, 9, 30), Date.new(2019, 12, 31), Date.new(2020, 3, 31) ], qtrs
end
end
```
In Rails there's the built-in prev_quarter and next_quarter.