DateBreakup

Pass two dates and get a breakdown of the range grouped into years, months, weeks, and days. Accepts Date, Time, or date strings.

Installation

Add this line to your application's Gemfile:

gem 'date_breakup'

Then run:

bundle install

Or install directly:

gem install date_breakup

Usage

All four methods return the same hash shape — { years:, months:, weeks:, days: } — with coarser arrays left empty depending on the method used.

.between accepts Date, Time, or a date string:

DateBreakup.between(Date.new(2019, 1, 1), Date.new(2019, 12, 31))
DateBreakup.between(Time.new(2019, 1, 1), Time.new(2019, 12, 31))
DateBreakup.between('01/01/2019', '31/12/2019')

Passing a start date after the end date raises ArgumentError.

in_years — greedy breakdown from years down

DateBreakup.between('01/01/2019', '31/12/2019').in_years
# => {
#   years:  [{ year: 2019, start_date: Sat 01 Jan 2019, end_date: Sat 31 Dec 2019 }],
#   months: [],
#   weeks:  [],
#   days:   []
# }

For a range that doesn't align to full years, the remainder falls through to months, weeks, and days:

DateBreakup.between('10/10/2010', '12/12/2012').in_years
# => {
#   years:  [{ year: 2011, start_date: Sat 01 Jan 2011, end_date: Sat 31 Dec 2011 }],
#   months: [
#     { month: 11, year: 2010, start_date: Mon 01 Nov 2010, end_date: Tue 30 Nov 2010 },
#     { month: 12, year: 2010, start_date: Wed 01 Dec 2010, end_date: Fri 31 Dec 2010 },
#     ...
#   ],
#   weeks:  [{ week: 41, month: 10, year: 2010, start_date: Mon 11 Oct 2010, end_date: Sun 17 Oct 2010 }, ...],
#   days:   [{ day: 283, month_day: 10, month: 10, year: 2010, start_date: Sun 10 Oct 2010, end_date: Sun 10 Oct 2010 }, ...]
# }

in_months — greedy breakdown from months down

DateBreakup.between('01/01/2019', '31/12/2019').in_months
# => {
#   years:  [],
#   months: [
#     { month: 1,  year: 2019, start_date: Tue 01 Jan 2019, end_date: Thu 31 Jan 2019 },
#     { month: 2,  year: 2019, start_date: Fri 01 Feb 2019, end_date: Thu 28 Feb 2019 },
#     ...
#     { month: 12, year: 2019, start_date: Sun 01 Dec 2019, end_date: Tue 31 Dec 2019 }
#   ],
#   weeks:  [],
#   days:   []
# }

in_weeks — greedy breakdown from weeks down

Partial weeks at the start or end of the range fall through to individual days.

DateBreakup.between('01/01/2019', '31/12/2019').in_weeks
# => {
#   years:  [],
#   months: [],
#   weeks: [
#     { week: 2, month: 1, year: 2019, start_date: Mon 07 Jan 2019, end_date: Sun 13 Jan 2019 },
#     ...
#     { week: 52, month: 12, year: 2019, start_date: Mon 23 Dec 2019, end_date: Sun 29 Dec 2019 }
#   ],
#   days: [
#     { day: 1, month_day: 1, month: 1, year: 2019, start_date: Tue 01 Jan 2019, end_date: Tue 01 Jan 2019 },
#     ...
#   ]
# }

in_days — every day individually

DateBreakup.between('01/01/2019', '03/01/2019').in_days
# => {
#   years:  [],
#   months: [],
#   weeks:  [],
#   days: [
#     { day: 1, month_day: 1, month: 1, year: 2019, start_date: Tue 01 Jan 2019, end_date: Tue 01 Jan 2019 },
#     { day: 2, month_day: 2, month: 1, year: 2019, start_date: Wed 02 Jan 2019, end_date: Wed 02 Jan 2019 },
#     { day: 3, month_day: 3, month: 1, year: 2019, start_date: Thu 03 Jan 2019, end_date: Thu 03 Jan 2019 }
#   ]
# }

Development

This project uses mise to manage the Ruby version.

# Install the required Ruby version
mise install

# Install dependencies
bin/setup

# Run tests
bundle exec rspec

# Run a single spec file
bundle exec rspec spec/date_breakup_spec.rb

# Open an interactive console with the gem loaded
bin/console

# Install the gem locally
bundle exec rake install

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/HuzaifaSaifuddin/date_breakup.

License

The gem is available as open source under the terms of the MIT License.