jonnyfolk has asked for the wisdom of the Perl Monks concerning the following question:

From an array @dates and using Date::Calc we can create a series of required calendar months:
while ( defined $dates[0] ) { my $days = $dates[0]; my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); my $new_c = new HTML::CalendarMonth ( year => $year, month => $mon +th ); }
How might I create the empty calendars of , say, June and July if the first date in @days creates a date in May, and the second a date in August?

Replies are listed 'Best First'.
Re: printing calendars using HTML::CalendarMonth
by borisz (Canon) on Feb 08, 2004 at 22:22 UTC
    Find the first date and the last. Then generate a cal for every month in between.
    Boris
      The lines I am currently thinking along is to analyse the difference between dates[0] and dates[1]. If the difference is 2 or more to insert calendars according to the difference. However I am still tripping up somewhere and I believe that it is the test on populating the calendar with days.

      Perhaps a kindly monk would show me the error of my ways...

      while ( defined $dates[0] ) { my $new_c; my $days = $dates[0]; my $days1 = $dates[1]; my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); my ( $year1, $month1, $day1 ); unless (! $days1) { ( $year1, $month1, $day1 ) = Add_Delta_Days( 1, 1, 1, $days1 - + 1 ); } my $diffmonth = $month1 - $month; if ($diffmonth >= 2) { my $count = 0; while ($count < $diffmonth) { $count += 1; $month++; $new_c = new HTML::CalendarMonth ( year => $year1, month = +> $month ); push (@cals, $new_c); } } else { $new_c = new HTML::CalendarMonth ( year => $year, month => $mo +nth ); push (@cals, $new_c); @dates = CreateCal( $year, $month, @dates ); push( @cals, $new_c ); } } # Embolden headers foreach my $calnum ( 0 .. $#cals ) { my $cal = $cals[$calnum]; if (@{ $days[$calnum] }) { my @color = @{ $days[$calnum] }; # the days to be colored } $cal->item( $cal->month, $cal->year )->wrap_content( font({ size => + '2' }) ); $cal->item( $cal->dayheaders )->wrap_content( font({ size => '2' }) + ); $cal->item( @color )->wrap_content( font({ size => 3, color => 'red +' }) ); } # Generate container table my $t = new HTML::ElementTable ( maxrow => 36, maxcol => 4 ); my $row = 0; # Populate container table for my $calnum ( 0 .. $#cals ) { my $col = $calnum % 4; my $row = int( $calnum / 4 ); $t->cell( $row, $col )->push_content( $cals[$calnum] ); } print $t->as_HTML; print end_html(); exit(0); sub CreateCal { my ( $cyear, $cmonth, @dates ) = @_; my ( @day, @temp ); foreach my $days ( @dates ) { my ( $year, $month, $day ) = Add_Delta_Days( 1, 1, 1, $days - 1 ); if ( $year == $cyear && $month == $cmonth ) { push ( @day, $day ); } else { push ( @temp, $days ); } } push ( @days, [ @day ] ); # store the days of each calendar return @temp; }
      Thanks due as always to Mr. Muskrat and mojotoad for their help with this code (the mistakes are my own :) )
        Im not sure if this is what you asked for. But maybe you can improve it.
        # creates a array of HTML::CalendarMonth from two dates # with every month inbetween. Dates are in days since 1.1.1 # # return arrayref of HTML::CalendarMonth objects. # sub create_cal { my ( $d, $d2 ) = sort @_; my @cal; my @d = Add_Delta_Days( 1, 1, 1, $d - 1 ); my @d2 = Add_Delta_Days( 1, 1, 1, $d2 - 1 ); while (1) { push @cal, HTML::CalendarMonth->new( year => $d[0], month => $d[1] + ); last if ( $d[0] == $d2[0] && $d[1] == $d2[1] ); if ( ++$d[1] > 12 ) { $d[0]++; $d[1] = 1; } } return \@cal; }
        Boris