From: Todd Benson Date: 2008-03-04T04:14:20+09:00 Subject: Re: making a monthly calendar... On Mon, Mar 3, 2008 at 1:02 PM, Todd Benson wrote: > > 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} That's one line and suppose to be today.month following today.year. > 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