making a monthly calendar...

Discussion in 'Ruby' started by Mikkel Bruun, Feb 29, 2008.

  1. Mikkel Bruun

    Mikkel Bruun Guest

    Hey

    I trying to do a calendar based app..

    So i have a monthly view with 5 weeks of 7 days = 35 boxes...

    Just like google calendar i need to show the selected month, and fill in
    the blanks with the previous and next months days...

    so february is ending today on a friday. So in the last 2 boxes of the
    5. week i need to show march 1 and 2 and the same in the front...

    I have this Month class. Which contains all the dates for a given month,
    as well as references to the next and previous months....

    there must be some kind of pattern im not getting bevause i keep
    slamming my head against the wall on this....

    anyone who have a quuck solution???

    thanks!!

    mikkel
    --
    Posted via http://www.ruby-forum.com/.
    Mikkel Bruun, Feb 29, 2008
    #1
    1. Advertising

  2. [Note: parts of this message were removed to make it a legal post.]

    Something like this?

    daniel@daniel-desktop:~$ cat /tmp/dats.rb
    require 'date'

    start_date = Date.civil(2007, 1, 27) # Must be a Sunday.
    0.upto(4 * 7 - 1) do |offset| # 4 weeks
    curr_date = start_date + offset
    print curr_date.mday.to_s.rjust(3)
    if offset % 7 == 6
    puts
    end
    end
    puts
    daniel@daniel-desktop:~$ ruby /tmp/dats.rb
    27 28 29 30 31 1 2
    3 4 5 6 7 8 9
    10 11 12 13 14 15 16
    17 18 19 20 21 22 23

    daniel@daniel-desktop:~$

    The formatting is better if you run it at the command line.

    Dan

    On Fri, Feb 29, 2008 at 5:30 PM, Mikkel Bruun <> wrote:

    > Hey
    >
    > I trying to do a calendar based app..
    >
    > So i have a monthly view with 5 weeks of 7 days = 35 boxes...
    >
    > Just like google calendar i need to show the selected month, and fill in
    > the blanks with the previous and next months days...
    >
    > so february is ending today on a friday. So in the last 2 boxes of the
    > 5. week i need to show march 1 and 2 and the same in the front...
    >
    > I have this Month class. Which contains all the dates for a given month,
    > as well as references to the next and previous months....
    >
    > there must be some kind of pattern im not getting bevause i keep
    > slamming my head against the wall on this....
    >
    > anyone who have a quuck solution???
    >
    > thanks!!
    >
    > mikkel
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >
    Daniel Finnie, Feb 29, 2008
    #2
    1. Advertising

  3. Mikkel Bruun

    Todd Benson Guest

    On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <> wrote:
    > Hey
    >
    > I trying to do a calendar based app..
    >
    > So i have a monthly view with 5 weeks of 7 days = 35 boxes...
    >
    > Just like google calendar i need to show the selected month, and fill in
    > the blanks with the previous and next months days...
    >
    > so february is ending today on a friday. So in the last 2 boxes of the
    > 5. week i need to show march 1 and 2 and the same in the front...
    >
    > I have this Month class. Which contains all the dates for a given month,
    > as well as references to the next and previous months....
    >
    > there must be some kind of pattern im not getting bevause i keep
    > slamming my head against the wall on this....
    >
    > anyone who have a quuck solution???
    >
    > thanks!!
    >
    > mikkel


    Here's one for fun. I'm pretty sure you don't want to use this (for
    all I know, you might be laughed out of the room :), but it
    demonstrates some methods...

    require 'enumerator'
    o = (t = Date.today).wday
    c = (-1..1).inject([]) {|a, i| a << (t.month + i)}.map {|i|
    1..Date.new( t.year, i, -1 ).day}.map {|i| i.to_a}
    o.times {c[1].unshift c[0].pop}
    c[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}

    You'd have to tidy up the output of course (using #join or whatever).
    Also, as you can see, 5 weeks doesn't necessarily cover a month. In
    March's calendar for 2008, there are 6 days out of February.

    Todd
    Todd Benson, Mar 1, 2008
    #3
  4. Mikkel Bruun

    Todd Benson Guest

    On Sat, Mar 1, 2008 at 1:51 AM, Todd Benson <> wrote:
    > On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <> wrote:
    > > anyone who have a quuck solution???
    > >
    > > thanks!!
    > >
    > > mikkel

    >
    > Here's one for fun. I'm pretty sure you don't want to use this (for
    > all I know, you might be laughed out of the room :), but it
    > demonstrates some methods...


    [snip beginning code]

    > c = (-1..1).inject([]) {|a, i| a << (t.month + i)}.map {|i|
    > 1..Date.new( t.year, i, -1 ).day}.map {|i| i.to_a}


    That is supposed to be one line, just so you know, if your reader
    didn't pick it up right.

    Todd
    Todd Benson, Mar 1, 2008
    #4
  5. Mikkel Bruun

    Mikkel Bruun Guest

    Todd Benson wrote:
    > On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <>
    > wrote:
    >> 5. week i need to show march 1 and 2 and the same in the front...
    >>
    >> mikkel

    >
    > Here's one for fun. I'm pretty sure you don't want to use this (for
    > all I know, you might be laughed out of the room :), but it
    > demonstrates some methods...
    >

    woot, it actually works....

    ive been doing ruby since 2000 but i cant undestand what the h*ll going
    on there....

    can you give me a walkthrough or a more humane rewrite ;-)

    --
    Posted via http://www.ruby-forum.com/.
    Mikkel Bruun, Mar 1, 2008
    #5
  6. Mikkel Bruun

    Todd Benson Guest

    On Sat, Mar 1, 2008 at 2:34 AM, Mikkel Bruun <> wrote:
    > Todd Benson wrote:
    > > On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <>
    > > wrote:

    >
    > >> 5. week i need to show march 1 and 2 and the same in the front...
    > >>

    >
    > >> mikkel

    > >
    > > Here's one for fun. I'm pretty sure you don't want to use this (for
    > > all I know, you might be laughed out of the room :), but it
    > > demonstrates some methods...
    > >

    > woot, it actually works....
    >
    > ive been doing ruby since 2000 but i cant undestand what the h*ll going
    > on there....
    >
    > can you give me a walkthrough or a more humane rewrite ;-)


    Okay, changing the code...

    <CODE>

    require 'enumerator'
    # I need that for the each_slice method later
    today = Date.today
    offset = today.wday
    # gives me the day of the week
    months_of_concern = (-1..1).inject([]) {|arr, i| arr << (today.month + i)}
    # just running through -1 to 1 and adding to the current month
    # it gives you last month, current month, and next month numbers
    # which will be handed to months_of_concern after the block finishes
    month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    month, -1 ).day}
    # building ranges to later turn into arrays
    # you get previous, current, and future month ranges
    # the month days
    # -1 is used, as Morton so excellently pointed out
    # as the _last_ number
    # this is common in Ruby

    day_sets = month_ranges.map {|i| i.to_a}
    # turning the Range objects (3 of them) into Array objects
    # I should have used {|i| i.map} here because it
    # would have been cuter, which is mostly disapproved
    # of in production code :)

    offset.times { day_sets[1].unshift day_sets[0].pop }
    # Here, we're just moving the last numbers of the last
    # month to the first part of this month one by one

    day_sets[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}
    # This one is actually easy to understand.
    # Grab what we now have as the current month,
    # tap on the ending month,
    # flatten it (turn it into one big array),
    # slice off the numbers that are in slots 0 to 35
    # compact (there might be nils)
    # each_slice simply builds arrays by
    # grabbing things 7 at a time.

    </CODE>

    Keep in mind scope. The "i" variable is local to each block; all by
    himself. It doesn't have to be "i", also.

    Todd
    Todd Benson, Mar 1, 2008
    #6
  7. Mikkel Bruun

    Todd Benson Guest

    On Sat, Mar 1, 2008 at 3:03 AM, Todd Benson <> wrote:
    >
    > On Sat, Mar 1, 2008 at 2:34 AM, Mikkel Bruun <> wrote:
    > > Todd Benson wrote:
    > > > On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <>
    > > > wrote:

    > >
    > > >> 5. week i need to show march 1 and 2 and the same in the front...
    > > >>

    > >
    > > >> mikkel
    > > >
    > > > Here's one for fun. I'm pretty sure you don't want to use this (for
    > > > all I know, you might be laughed out of the room :), but it
    > > > demonstrates some methods...
    > > >

    > > woot, it actually works....
    > >
    > > ive been doing ruby since 2000 but i cant undestand what the h*ll going
    > > on there....
    > >
    > > can you give me a walkthrough or a more humane rewrite ;-)

    >
    > Okay, changing the code...
    >
    > <CODE>
    >
    > require 'enumerator'
    > # I need that for the each_slice method later
    > today = Date.today
    > offset = today.wday
    > # gives me the day of the week
    > months_of_concern = (-1..1).inject([]) {|arr, i| arr << (today.month + i)}
    > # just running through -1 to 1 and adding to the current month
    > # it gives you last month, current month, and next month numbers
    > # which will be handed to months_of_concern after the block finishes
    > month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    > month, -1 ).day}
    > # building ranges to later turn into arrays
    > # you get previous, current, and future month ranges
    > # the month days
    > # -1 is used, as Morton so excellently pointed out
    > # as the _last_ number
    > # this is common in Ruby
    >
    > day_sets = month_ranges.map {|i| i.to_a}
    > # turning the Range objects (3 of them) into Array objects
    > # I should have used {|i| i.map} here because it
    > # would have been cuter, which is mostly disapproved
    > # of in production code :)
    >
    > offset.times { day_sets[1].unshift day_sets[0].pop }
    > # Here, we're just moving the last numbers of the last
    > # month to the first part of this month one by one
    >
    > day_sets[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}
    > # This one is actually easy to understand.
    > # Grab what we now have as the current month,
    > # tap on the ending month,
    > # flatten it (turn it into one big array),
    > # slice off the numbers that are in slots 0 to 35
    > # compact (there might be nils)
    > # each_slice simply builds arrays by
    > # grabbing things 7 at a time.
    >
    > </CODE>
    >
    > Keep in mind scope. The "i" variable is local to each block; all by
    > himself. It doesn't have to be "i", also.


    My apologies, this was aimed at newbies, not at you.

    Todd
    Todd Benson, Mar 1, 2008
    #7
  8. Mikkel Bruun

    Mikkel Bruun Guest

    Todd Benson wrote:
    > On Sat, Mar 1, 2008 at 3:03 AM, Todd Benson <> wrote:
    >> > >

    >>
    >> # just running through -1 to 1 and adding to the current month
    >>
    >> day_sets[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}
    >>
    >> Keep in mind scope. The "i" variable is local to each block; all by
    >> himself. It doesn't have to be "i", also.

    >
    > My apologies, this was aimed at newbies, not at you.
    >
    > Todd


    no problem...

    thanks for your reply...ill see wha i can make of it...
    --
    Posted via http://www.ruby-forum.com/.
    Mikkel Bruun, Mar 1, 2008
    #8
  9. Mikkel Bruun

    Todd Benson Guest

    On Sat, Mar 1, 2008 at 5:45 AM, Mikkel Bruun <> wrote:
    > Todd Benson wrote:
    > > On Sat, Mar 1, 2008 at 3:03 AM, Todd Benson <> wrote:
    > >> > >
    > >>

    >
    > >> # just running through -1 to 1 and adding to the current month
    > >>

    >
    > >> day_sets[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}
    > >>

    >
    > >> Keep in mind scope. The "i" variable is local to each block; all by
    > >> himself. It doesn't have to be "i", also.

    > >
    > > My apologies, this was aimed at newbies, not at you.
    > >
    > > Todd

    >
    > no problem...
    >
    > thanks for your reply...ill see wha i can make of it...


    Thanks for the exercise. I've been meaning to make use of a graphical
    calendar for a while, and now you've given me an excuse to finish it!

    Todd
    Todd Benson, Mar 1, 2008
    #9
  10. Mikkel Bruun

    Todd Benson Guest

    Oh my goodness! A thousand apologies. I gave you a rotating month. See below.

    On Sat, Mar 1, 2008 at 3:03 AM, Todd Benson <> wrote:
    >
    > On Sat, Mar 1, 2008 at 2:34 AM, Mikkel Bruun <> wrote:
    > > Todd Benson wrote:
    > > > On Fri, Feb 29, 2008 at 4:30 PM, Mikkel Bruun <>
    > > > wrote:

    > >
    > > >> 5. week i need to show march 1 and 2 and the same in the front...
    > > >>

    > >
    > > >> mikkel
    > > >
    > > > Here's one for fun. I'm pretty sure you don't want to use this (for
    > > > all I know, you might be laughed out of the room :), but it
    > > > demonstrates some methods...
    > > >

    > > woot, it actually works....
    > >
    > > ive been doing ruby since 2000 but i cant undestand what the h*ll going
    > > on there....
    > >
    > > can you give me a walkthrough or a more humane rewrite ;-)

    >
    > Okay, changing the code...
    >
    > <CODE>
    >
    > require 'enumerator'
    > # I need that for the each_slice method later
    > today = Date.today


    offset = Date.new(today.year, today.month, 1).wday

    > # gives me the day of the week
    > months_of_concern = (-1..1).inject([]) {|arr, i| arr << (today.month + i)}
    > # just running through -1 to 1 and adding to the current month
    > # it gives you last month, current month, and next month numbers
    > # which will be handed to months_of_concern after the block finishes
    > month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    > month, -1 ).day}
    > # building ranges to later turn into arrays
    > # you get previous, current, and future month ranges
    > # the month days
    > # -1 is used, as Morton so excellently pointed out
    > # as the _last_ number
    > # this is common in Ruby
    >
    > day_sets = month_ranges.map {|i| i.to_a}
    > # turning the Range objects (3 of them) into Array objects
    > # I should have used {|i| i.map} here because it
    > # would have been cuter, which is mostly disapproved
    > # of in production code :)
    >
    > offset.times { day_sets[1].unshift day_sets[0].pop }
    > # Here, we're just moving the last numbers of the last
    > # month to the first part of this month one by one
    >
    > day_sets[1..2].flatten.slice(0..35).compact.each_slice(7) {|i| p i}
    > # This one is actually easy to understand.
    > # Grab what we now have as the current month,
    > # tap on the ending month,
    > # flatten it (turn it into one big array),
    > # slice off the numbers that are in slots 0 to 35
    > # compact (there might be nils)
    > # each_slice simply builds arrays by
    > # grabbing things 7 at a time.
    >
    > </CODE>
    >
    > Keep in mind scope. The "i" variable is local to each block; all by
    > himself. It doesn't have to be "i", also.


    My original code only worked when run on the first of the month.
    Pretty funny, actually. It's one of those things that a unit test
    wouldn't catch unless the test was written correctly.

    Todd
    Todd Benson, Mar 3, 2008
    #10
  11. Mikkel Bruun

    Mikkel Bruun Guest

    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+1}
    i=0
    #pad with previous
    1.upto(offset){boxes=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+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??
    --
    Posted via http://www.ruby-forum.com/.
    Mikkel Bruun, Mar 3, 2008
    #11
  12. Mikkel Bruun

    Todd Benson Guest

    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+1}
    > i=0
    > #pad with previous
    > 1.upto(offset){boxes=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+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
    Todd Benson, Mar 3, 2008
    #12
  13. Mikkel Bruun

    Todd Benson Guest

    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+1}
    > > i=0
    > > #pad with previous
    > > 1.upto(offset){boxes=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+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
    Todd Benson, Mar 3, 2008
    #13
  14. Mikkel Bruun

    Mikkel Bruun Guest

    Todd Benson wrote:
    > On Mon, Mar 3, 2008 at 1:02 PM, Todd Benson <> wrote:
    >> > offset.upto(days.length+offset){boxes[offset+i]=days;i=i+1}
    >> > boxes array into parts of 7

    >> with the correct number of days in each, centered around the current
    >> display, but, obviously, you won't have to do that, because you have
    >>
    >> 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


    thanks for all your help

    but your code seems to break when changing years. showing january 2008
    breaks when populating decemeber 2007 etc...

    i believe this line has to take this into account:

    month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    month, -1 ).day}


    Mikkel
    --
    Posted via http://www.ruby-forum.com/.
    Mikkel Bruun, Mar 3, 2008
    #14
  15. There's a calendar_helper plugin if this is for a Rails app. Works well for me.

    --Jeremy

    On Mon, Mar 3, 2008 at 3: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+1}
    > i=0
    > #pad with previous
    > 1.upto(offset){boxes=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+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??
    >
    >
    > --
    > Posted via http://www.ruby-forum.com/.
    >
    >




    --
    http://jeremymcanally.com/
    http://entp.com

    Read my books:
    Ruby in Practice (http://manning.com/mcanally/)
    My free Ruby e-book (http://humblelittlerubybook.com/)

    Or, my blogs:
    http://mrneighborly.com
    http://rubyinpractice.com
    Jeremy McAnally, Mar 3, 2008
    #15
  16. Mikkel Bruun

    Todd Benson Guest

    On Mon, Mar 3, 2008 at 2:14 PM, Mikkel Bruun <> wrote:
    > Todd Benson wrote:
    > > On Mon, Mar 3, 2008 at 1:02 PM, Todd Benson <> wrote:

    >
    > >> > offset.upto(days.length+offset){boxes[offset+i]=days;i=i+1}

    >
    > >> > boxes array into parts of 7

    >
    > >> with the correct number of days in each, centered around the current

    >
    > >> display, but, obviously, you won't have to do that, because you have
    > >>

    >
    > >> 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

    >
    > thanks for all your help
    >
    > but your code seems to break when changing years. showing january 2008
    > breaks when populating decemeber 2007 etc...
    >
    > i believe this line has to take this into account:
    >
    >
    > month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    > month, -1 ).day}
    >
    >
    > Mikkel


    Yeah, I just realized the edge cases of January and December fail. I
    thought the Date object covered that with a -1 or 13 month.

    I'm looking into it right now. You might be better off subtracting a
    week and adding a week for your big array. For example...

    puts Date.new(2008, 1, 5) - 7

    => 2007-12-29

    Todd
    Todd Benson, Mar 3, 2008
    #16
  17. Mikkel Bruun

    Todd Benson Guest

    On Mon, Mar 3, 2008 at 2:43 PM, Todd Benson <> wrote:
    >
    > On Mon, Mar 3, 2008 at 2:14 PM, Mikkel Bruun <> wrote:
    > Yeah, I just realized the edge cases of January and December fail. I
    > thought the Date object covered that with a -1 or 13 month.
    >
    > I'm looking into it right now. You might be better off subtracting a
    > week and adding a week for your big array. For example...
    >
    > puts Date.new(2008, 1, 5) - 7
    >
    > => 2007-12-29


    No, actually the same code works, you just have to turn the -1..1
    range into a loop for 12, which can be done like this...

    your_number % 12 + 1

    so code would be...

    require 'date'
    today = Date.new(2008, 1, 8)#use whatever date you want
    offset = Date.new(today.year, today.month, 1).wday
    months_of_concern = (-1..1).map.inject([]) {|arr, i| arr << (today.month + i)}
    months_of_concern.map! {|i| i % 12 + 1}
    month_ranges = months_of_concern.map {|month| 1..Date.new( today.year,
    month, -1 ).day}
    day_sets = month_ranges.map {|i| i.to_a}
    offset.times { day_sets[1].unshift day_sets[0].pop }
    p day_sets[1..2].flatten.slice(0..42)

    Todd
    Todd Benson, Mar 3, 2008
    #17
  18. Mikkel Bruun

    Todd Benson Guest

    On Mon, Mar 3, 2008 at 2:37 PM, Jeremy McAnally
    <> wrote:
    > There's a calendar_helper plugin if this is for a Rails app. Works well for me.
    >
    > --Jeremy


    I agree. If this is to be productive, then you probably don't have to
    reinvent the wheel :)

    Todd
    Todd Benson, Mar 3, 2008
    #18
  19. Todd Benson wrote:
    > On Mon, Mar 3, 2008 at 2:37 PM, Jeremy McAnally
    > <> wrote:
    >> There's a calendar_helper plugin if this is for a Rails app. Works well for me.
    >>
    >> --Jeremy

    >
    > I agree. If this is to be productive, then you probably don't have to
    > reinvent the wheel :)
    >
    > Todd


    Yes. Here is my effort anyway:

    require 'date'
    require 'enumerator'

    def days_to_show(year, month, num_week_rows)
    # returns an array of the dates in month,
    # with the last days of the preceding month
    # and the first days of the next month

    first_of_month = Date.new(year, month, 1)
    first = first_of_month - (first_of_month.wday)+1
    # +1 for weeks starting on monday, remove for weeks starting on sunday
    last = first + (num_week_rows * 7)
    (first...last).to_a
    end

    days = days_to_show(2008, 3, 6)
    days.each_slice(7) do |week|
    print "| "
    week.each{|day| print day.to_s + "\t| "}
    puts
    end

    The only thing noteworthy is the range of dates, which produces an
    array.

    Regards,

    Siep
    --
    Posted via http://www.ruby-forum.com/.
    Siep Korteling, Mar 3, 2008
    #19
  20. Mikkel Bruun

    Todd Benson Guest

    On Mon, Mar 3, 2008 at 4:52 PM, Siep Korteling <> wrote:
    >
    > Todd Benson wrote:
    > > On Mon, Mar 3, 2008 at 2:37 PM, Jeremy McAnally
    > > <> wrote:
    > >> There's a calendar_helper plugin if this is for a Rails app. Works well for me.
    > >>
    > >> --Jeremy

    > >
    > > I agree. If this is to be productive, then you probably don't have to
    > > reinvent the wheel :)
    > >
    > > Todd

    >
    > Yes. Here is my effort anyway:
    >
    > require 'date'
    > require 'enumerator'
    >
    > def days_to_show(year, month, num_week_rows)
    > # returns an array of the dates in month,
    > # with the last days of the preceding month
    > # and the first days of the next month
    >
    > first_of_month = Date.new(year, month, 1)
    > first = first_of_month - (first_of_month.wday)+1
    > # +1 for weeks starting on monday, remove for weeks starting on sunday
    > last = first + (num_week_rows * 7)
    > (first...last).to_a
    > end
    >
    > days = days_to_show(2008, 3, 6)
    > days.each_slice(7) do |week|
    > print "| "
    > week.each{|day| print day.to_s + "\t| "}
    > puts
    > end
    >
    > The only thing noteworthy is the range of dates, which produces an
    > array.
    >
    > Regards,
    >
    > Siep


    Mikkel, this is excellent use of the Date#- and Date#+ methods, and a
    much better approach. I still think my solution is more fun :)

    Todd
    Todd Benson, Mar 3, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Johnny Williams
    Replies:
    0
    Views:
    447
    Johnny Williams
    Dec 2, 2003
  2. Diana Sanders
    Replies:
    0
    Views:
    370
    Diana Sanders
    Dec 2, 2003
  3. Falcon2005
    Replies:
    0
    Views:
    344
    Falcon2005
    Feb 6, 2005
  4. Monthly Calendar Control

    , Aug 18, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    363
    Bruno Alexandre
    Aug 18, 2006
  5. Michael Rich

    Printed Monthly Calendar Controls

    Michael Rich, Apr 10, 2005, in forum: ASP .Net Web Controls
    Replies:
    2
    Views:
    132
    Andrew Smith \(Infragistics\)
    Apr 16, 2005
Loading...

Share This Page