カレンダーを作る
お仕事でカレンダープログラムを作ることになって、『簡単CGI: カレンダーを作ろう』なんかを参考にとりあえずクラスを作る。(長いので)一部削除しているが、公開されているものを参考にさせていただいたので、感謝を込めて肝のところだけ私も公開。
package Calendar; # Copyright(c) 2005, Tetsuya TOYODA. # mailto: altair@dream.big.jp # # This program is free software; # you may redistribute it and/or modify it # under the same terms as Perl itself. use strict; sub new { my $obj = shift; my %hash = @_; my( $year, $month ) = ( gmtime ( time + 9 * 60 * 60 ) )[5,4]; $year += 1900; $month += 1; my $start_wday = 0; my $blank = ''; $year = $hash{'year'} if $hash{'year'}; $month = $hash{'month'} if $hash{'month'}; $start_wday = $hash{'start_wday'} if $hash{'start_wday'}; $blank = $hash{'blank'} if $hash{'blank'}; bless { year => $year, month => $month, start_wday => $start_wday, blank => $blank }, $obj; } sub output { my $self = shift; my $table; my @last_days = (31,28,31,30,31,30,31,31,30,31,30,31); my $year = $self->{year}; my $month = $self->{month}; if( ( ($year % 4 == 0 ) && ( $year % 100 != 0 ) ) || ( $year % 400 == 0 ) ){ $last_days[1]=29; } my $start = _wday($year,$month,1); my $last_day = $last_days[$month-1]; my $col = 0; my $row = 0; my $day = 0; $table->[0]->{num} = 1; while( $start-- ){ $table->[$row]->{week}->[$col++] = { day => $self->{blank} }; } while( $last_day-- ){ $table->[$row]->{week}->[$col++]->{day} = ++$day; if ( $col >= 7 ){ $row++; $col = 0; } } if( $col ){ my $tail = 7 - $col; while( $tail-- ){ $table->[$row]->{week}->[$col++] = { day => $self->{blank} }; } } return $table; } sub year { my $self = shift; my $year = shift; $self->{year} = $year if $year; return $self->{year}; } sub month { my $self = shift; my $month = shift; $self->{month} = $month if $month; return $self->{month}; } sub start_wday { my $self = shift; my $start_wday = shift; $self->{start_wday} = $start_wday if $start_wday; return $self->{year}; } sub blank { my $self = shift; my $blank = shift; $self->{blank} = $blank if $blank; return $self->{blank}; } ### ### ### ### ### sub _wday { my ( $year, $month, $day ) = @_; if ( $month < 3 ){ $month += 12; $year--; } return ( $year + int ( $year / 4 ) - int( $year / 100 ) + int ( $year / 400 ) + int ( ( 13 * $month + 8 ) / 5 ) + $day ) % 7; } 1;
outputメソッドを実行すると、カレンダーを構造体として得ることが出来る。そのままテンプレートシステムに渡せばテーブルになる。例えば、HTML::Templateなら以下のようなテンプレートだろうか。
<table> <tr> <th>SUN</th> <th>MON</th> <th>TUE</th> <th>WED</th> <th>THU</th> <th>FRI</th> <th>SAT</th> </tr> <TMPL_LOOP month> <tr> <TMPL_LOOP week> <td> <div class="day"><TMPL_VAR day></div> </td> </TMPL_LOOP> </tr> </TMPL_LOOP> </table>
例えば次のように使う。
use Calendar; use HTML::Template; # Calendarのインスタンスを得る my $cal = new Calendar; # HTML::Templateのインスタンスを得る # テンプレートはcal.tmpl my $tmpl = new HTML::Template filename => 'cal.tmpl'; # カレンダーの空欄部に入れる文字列を設定 $cal->blank(' '); # テンプレートに構造体をセット $tmpl->param( month => $cal->output ); # 出力 print "Content-Type: text/html;charset=UTF-8?n?n"; print $tmpl->output; exit;