lib/calrom/date_range.rb in calrom-0.1.0 vs lib/calrom/date_range.rb in calrom-0.2.0

- old
+ new

@@ -1,34 +1,104 @@ module Calrom class DateRange < Range + def each_month + return to_enum(:each_month) unless block_given? + + if first.year == last.year && first.month == last.month + # a single month or it's part + yield self + return + end + + (Month.new(first.year, first.month) .. Month.new(last.year, last.month)) + .each_with_index do |m,i| + if i == 0 && first.day > 1 + # first month, incomplete + end_of_month = first.next_month - first.day + 1 + yield self.class.new(first, m.last) + elsif m.first.year == last.year && m.first.month == last.month && last != m.last + # last month, incomplete + yield self.class.new(m.first, last) + else + yield m + end + end + end end class Year < DateRange def initialize(year) super Date.new(year, 1, 1), Date.new(year, 12, 31) end def to_s first.year.to_s end + + def each_month + return to_enum(:each_month) unless block_given? + + 1.upto(12) {|month| yield Month.new(first.year, month) } + end end class Month < DateRange def initialize(year, month) - super Date.new(year, month, 1), Date.new(year, month + 1, 1) - 1 + @year = year + @month = month + super Date.new(year, month, 1), next_month_beginning - 1 end def to_s - "#{first.month}/#{first.year}" + first.strftime '%B %Y' end + + def each_month + return to_enum(:each_month) unless block_given? + + yield self + end + + def succ + n = next_month_beginning + self.class.new(n.year, n.month) + end + + def <=>(other) + years_cmp = year <=> other.year + + if years_cmp != 0 + years_cmp + else + month <=> other.month + end + end + + protected + + attr_reader :year, :month + + private + + def next_month_beginning + if @month == 12 + Date.new(@year + 1, 1, 1) + else + Date.new(@year, @month + 1, 1) + end + end end class Day < DateRange def initialize(date) super date, date end def to_s first.to_s + end + + def each_month + yield self end end end