SOURCE
menu.pm
sub panel_content{
my $s = shift;
my $m = $s->app->model;
my $text = <<END_SCRIPT
<pre>
@{[`date +"%a %b %d %Y"`]}
@{[$m->make_cal($m->today())]}
</pre>
END_SCRIPT
}
model.pm
sub make_days{
my ($s,$y,$m,$d,$dumy) = @_;
my @days = map{[$y,$m,$_]} (1 .. $s->end_day($y*100+$m));
my $w = $s->getwday($y,$m,$s->end_day($y*100+$m));
my ($yy,$mm,$dd) = (0,0,0);
for ($w+1 .. 6){
($yy,$mm,$dd) = $s->adddate($y,$m,$s->end_day($y*100+$m),$dd+1);
push(@days,[$yy,$mm,$dd]);
}
$d = 1;
$w = $s->getwday($y,$m,$d);
while($w--){
($y,$m,$d) = $s->adddate($y,$m,$d,-1);
unshift(@days,[$y,$m,$d]);
}
return @days;
}
sub make_cal{
my ($s,$y,$m,$d,$dumy) = @_;
my $cal = '';
$cal .= "<table border=0 width=50%>";
$cal .= $s->tag("tr",$s->tag("td",qw(日 月 火 水 木 金 土)));
my $i = 0;
$cal .= join ("",map {$s->day_class($i++,$y,$m,$_) } $s->make_days($y,$m,$d));
$cal .= "</table>";
return $cal;
}
sub day_class{
my ($s,$i,$y,$m,$d) = @_;
my $text ='';
my $class = $s->holiday(-date=>$d->[0]*10000+$d->[1]*100+$d->[2]);
if($class ne ''){
$class = 'hol';
}else{
$class = qw(Sun Mon Tue Wed Thu Fri Sat)[$i % 7];
}
$class .= ' today' if ($s->isToday($d->[0],$d->[1],$d->[2]));
$class = 'Non' if($m != $d->[1]);
$text .= '<tr>' if($i % 7 == 0);
$text .= qq{<td class="$class">$d->[2]</td>};
$text .= '</tr>' if($i % 7 == 6);
return $text;
}
#------------------------------------------------------------------
sub holiday{
#------------------------------------------------------------------
=head2 祝日計算 [holiday]
=over 2
祝日なら祝日の名前を返す
=item $name = holiday(-date=>YYYYMMDD)
西暦年月日より祝日の判断を行う
=back
=cut
my $s = shift;
my %x = (
1 => {1 => "元旦",},
2 => {11 => "建国記念日",
23 => "天皇誕生日"},
4 => {29 => "昭和の日",},
5 => {3 => "憲法記念日",
4 => "みどりの日",
5 => "こどもの日",},
8 => {11 => "山の日",},
11 => {3 => "文化の日",
23 => "勤労感謝の日",},
@_);
my($y,$m,$d) = $s->ymd_split($x{-date});
$m = $m+0;
$d = $d+0;
$x{1}{$s->get_w_day($y,1,2,1)} = "成人の日";
$x{7}{$s->get_w_day($y,7,3,1)} = "海の日";
$x{9}{$s->get_w_day($y,9,3,1)} = "敬老の日";
$x{10}{$s->get_w_day($y,10,2,1)} = "スポーツの日";
my ($vernal,$autumnal)=$s->get_equinox_day($y);
$x{3}{$vernal} = "春分の日";
$x{9}{$autumnal} = "秋分の日";
my($yy,$mm,$dd) = $s->adddate($y,$m,$d,-1);
if($s->getwday($yy,$mm,$dd) == 0 and defined $x{$mm}{$dd}){
$x{$m}{$d} = "振替の休日";
}
if($s->getwday($yy,5,5) <= 2){
$x{5}{6} = "国民の休日";
}
return $x{$m}{$d};
}
#------------------------------------------------------------------
sub get_w_day{
#------------------------------------------------------------------
=head2 $y年$m月第$n曜日の日を返す [get_w_day]
=over 2
=item $d = get_w_day($y,$m,$n,$wday)
$y: 年
$m: 月
$n: 第何曜日かを指定[1〜5]
$n: 曜日 [0〜6] (0:日曜 1:月曜 2:火曜 3:水曜 4:木曜 5:金曜 6:土曜)
$d: 対象の日付を返す
=back
=cut
my $s = shift;
my ($y,$m,$n,$wday) = @_;
my $st_wday = $s->getwday($y,$m,1);
my $end_day = $s->end_day($y*100+$m);
my $d;
if($wday >= $st_wday){$n--;}
$d = 7 * $n + $wday + 1 - $st_wday;
if($d > $end_day or $d <= 0){$d = '';}
return $d;
}
#------------------------------------------------------------------
sub get_equinox_day{
#------------------------------------------------------------------
=head2 春分の日と秋分の日を求める [get_equinox_day]
=over 2
指定した年の春分日・秋分日をもとめる
(1980年から2099年に適用)
($vernal,$autumnal)=get_equinox_day($y);
=back
=cut
my $s = shift;
my ($yy)=@_;
my ($vernal) = int(20.8431+0.242194*($yy-1980)-int(($yy-1980)/4));
my ($autumnal)=int(23.2488+0.242194*($yy-1980)-int(($yy-1980)/4));
return ($vernal,$autumnal);
}
#------------------------------------------------------------------
sub end_day{
#------------------------------------------------------------------
=head2 末日算出 [end_day]
=over 2
入力年月から末日を計算する。
=item $day = end_day($DATE)
$DATE: 日付 YYYYMM or YYYY/MM
$day: $DATEの末日(28or29or30or31)
=back
=cut
my $s = shift;
my $yymm = shift;
my @end = (31,28,31,30,31,30,31,31,30,31,30,31);
$yymm =~ /^(\d{1,4})\D*(\d{1,2})$/;
my ($y,$m) = ($1,$2);
if($2 != 2){return $end[$m - 1];}
if($y % 400 == 0 or $y % 100 != 0 and $y %4 == 0){
return 29;
}else{ return $end[$m - 1];}
}
.Sun{color:RED;}
.Sat{color:BLUE;}
.hol{color:RED;}
.today{
box-shadow: 3px 3px 7px 1px rgba(0,0,0,0.4);
transform: scale(1.05,1.05);
}
.Non{color:GRAY;}