Weeks in a Month Calculations

→ January 5th, 2010

I was bitten by a nuance in Ruby where the Date “2010/01/01″ is actually the 53rd week in 2009.  I probably don’t fully understand how the cweek method works, but to see it in action, fire up irb and try:

Date.civil(2010,1,1).cweek

I needed a new way to calculate all of the weeks in month and my old solution was a hack, so I came up with another quick hack to get it right.  Below is my code to extend Date and Time to return an array of ranges for every week in a month.

module ActiveSupport #:nodoc:
  module CoreExtensions #:nodoc:

    module Date #:nodoc:
      module MyCalculations
        # Return an array of ranges with the weeks in the month
        def weeks_in_month
          weeks = []
          start = finish = beginning_of_month

          while finish != end_of_month
            finish = start.end_of_week
            finish = end_of_month if finish > end_of_month
            weeks << (start..finish)

            start = finish + 1.day
            start = start.beginning_of_day
          end

          weeks
        end
      end
    end

    module Time #:nodoc:
      module MyCalculations
        # Return an array of ranges with the weeks in the month
        def weeks_in_month
          weeks = []
          start = finish = beginning_of_month

          while finish != end_of_month
            finish = start.end_of_week
            finish = end_of_month if finish > end_of_month
            weeks << (start..finish)

            start = finish + 1.day
            start = start.beginning_of_day
          end

          weeks
        end
      end
    end
  end
end

class Date
  include ActiveSupport::CoreExtensions::Date::MyCalculations
end

class Time
  include ActiveSupport::CoreExtensions::Time::MyCalculations
end
blog comments powered by Disqus