From: Max Muermann Date: 2006-10-19T07:37:43+09:00 Subject: Re: too complex for me... On 10/19/06, Josselin wrote: > I need help from a ruby master... it's too hard with my present > understanding, any starting key will be apprciated .... > > from a period range [start_date, end_date] in ayear , I need to > produce a list of special days like the following : > ["2006-10-12","2006-11-08"] => { 10 : [ 12 , 31], 11 : [ 1, 8] } > or > ["2006-10-12","2006-12-08"] => { 10 : [ 12 , 31], 11 : [ 1, 30] , 12 > : [ 1, 12] } > which means, for each month in the range > the month number : [ period covered in the month] , > > where 'period covered in the month' is > [ 1st day of the period or 1st day of the month , last day of the > period or last day of the month ] > > coudl I get any clue ? > > thanks a lot > > joss > I had to make a change to the return values. They are now an array (to maintain order), with the first element being a string looking like "2006-10", as the code works for multiple dates, the second element is an array with the period covered. Lots of special case code for handling year boundaries. I'm sure this can be tightened up, I'd be interested to hear views as to how... require 'date' def coverage rg from = Date.parse(rg[0]) to = Date.parse(rg[1]) cover = [] # build a list of all month indexes we need to iterate over if from.year==to.year # trivial case, both dates fall within the same year month_range = (from.month..to.month ) else # complex case - dates in different years # first year - form month to december month_range = (from.month..12).to_a # more than one year covered? (to.year-from.year-1).times do |year| # jan to dec month_range += (1..12).to_a end # last year - jan to to.month month_range += (1..to.month).to_a end y = from.year month_range.each do |m| if from < Date.new(y,m,1) first_day = 1 else first_day = from.day end # passing -1 as the day gets the last day of the month end_of_month = Date.new(y,m,-1) if to > end_of_month last_day = end_of_month.day else last_day = to.day end cover << ["#{y}-#{m}",[first_day, last_day]] # next year? y +=1 if m==12 end cover end p coverage(["2006-10-12","2008-02-12"]) Cheers, Max