From: Todd Benson Date: 2008-03-04T04:02:32+09:00 Subject: Re: making a monthly calendar... On Mon, Mar 3, 2008 at 2:05 AM, Mikkel Bruun wrote: > So I ended up with: > > def calendar_view > firstday = days[0] #all days in month > offset = firstday.wday-1 > boxes =Array.new(5*7) # the viewport > i=0 > #this month from wday of firstday > offset.upto(days.length+offset){boxes[offset+i]=days[i];i=i+1} > i=0 > #pad with previous > 1.upto(offset){boxes[i]=previous.days[-offset+i];i=i+1} > i=0 > #pad with next... > (offset+days.length).upto(boxes.length){boxes[days.length+i+offset]=next_month.days[i];i=i+1} > return boxes > end > > I show this in a rails app using array.groups_of(7) which chops the > boxes array into parts of 7 > > which works ok...untill i hit june 08....where the first week starts > with jun 2nd... > > How are your algorithms working?? You can use my code (with the correction in my last post), and omit the each_slice part (you do want one big array right?). To explain what I was doing in a different way, I build three arrays with the correct number of days in each, centered around the current month (that's why I add -1, 0, and 1 to the current month number). I use (didn't with the first code, sorry) the first day of the current month as the offset. I build ranges after I get the month numbers, then build arrays off those ranges. So I have a single array of three arrays. When I #pop off the first array and #unshift _onto_ the second array, it moves the last day number of the previous month array onto the first day of the current month array; sort of what you are doing by hand. I do this offset number of times using the #times method. Then I flatten (the weird current month array rolled into the next month array -- the use of the 1..2 range). I used each_slice for display, but, obviously, you won't have to do that, because you have #groups_of. Just flatten and slice. In any case, google calendar uses a 7 x 7 grid. I would recommend at least a 7 x 6 grid for reasons I pointed out earlier. When you display March, for example, you will only go up to 29 with 7 x 5. Here's the script code without the previous comments, and surreptitiously using a 7 x 6 grid (I still would code this differently by separating out into methods, and also probably a Month and/or Calendar class)... today = Date.today #use whatever date you want offset = Date.new(today.year, today.month, 1).wday # ^^^^^^ that was the line I screwed up at first months_of_concern = (-1..1).inject([]) {|a, i| a << (today.month + i)} month_ranges = months_of_concern.map {|month| 1..Date.new( today.year, month, -1 ).day} day_sets = month_ranges.map {|i| i.map} offset.times {day_sets[1].unshift day_sets[0].pop} p day_sets[1..2].flatten.slice(0..42) Todd