完成品

<?php
function svgstart(){
header('Content-type: image/svg+xml');
print <<<EOD1
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="layer1"
 xmlns="http://www.w3.org/2000/svg"
 xmlns:xlink="http://www.w3.org/1999/xlink"
 x="0px" y="0px"
 viewBox="0 0 841.9 595.3"
 style="enable-background:new 0 0 841.9 595.3;"
 xml:space="preserve">
<style type="text/css">
       .mfont{font-size:18pt;}
       .m3font{font-size:9px;}
       .wfont{font-size:8pt;text-anchor:middle;}
       .dfont{font-size:11pt;text-anchor:middle;fill:white;}
       .dfont2{font-size:8pt;text-anchor:middle;fill:white;}
	   .c01{fill:#F8C17C;} .c02{fill:#F29A5A;} .c03{fill:#ED7235;}
	   .c11{fill:#EFA682;} .c12{fill:#D15563;} .c13{fill:#D91D2C;}
	   .c21{fill:#A1B2DB;} .c22{fill:#546FB5;} .c23{fill:#1A3895;}
	   .c31{fill:#A8DBEF;} .c32{fill:#60C5E9;} .c33{fill:#2EA7E0;}
	   .c41{fill:#B2DAB3;} .c42{fill:#75C397;} .c43{fill:#20A266;}
	   .c51{fill:#F2C7DD;} .c52{fill:#EB9EB9;} .c53{fill:#E87BAD;}
</style>
EOD1;
}
function svgend() {
       print "</svg>\n";
}

function svgmonth($nen,$month,$bx=40,$by=40,$color=0) {
        $holi1 = array(
                array(11,3,"文化の日"),
                array(11,23,"勤労感謝の日"),
                array(12,23,"天皇誕生日"),
                array(1,1,"元日"),
                array(2,11,"建国記念日"),
                array(4,29,"昭和の日"),
                array(5,3,"憲法記念日"),
                array(5,4,"みどりの日"),
                array(5,5,"こどもの日"),
                array(8,11,"山の日"),
        );
        $holi2 = array(
                array(1,2,"成人式"),
                array(7,3,"海の日"),
                array(9,3,"敬老の日"),
                array(10,2,"体育の日"),
        );
        if($month==3) {
                $n=(int)(20.8431+0.242194*($nen-1980))-(int)(($nen-1980)/4);
                array_push($holi1,array(3,$n,"春分の日"));
        }
        if($month==9) {
                $n=(int)(23.2488+0.242194*($nen-1980))-(int)(($nen-1980)/4);
                array_push($holi1,array(9,$n,"秋分の日"));
                $stday = new DateTime($nen.'-'.$month.'-'.$n);
                $w = (int)$stday->format('w');
                if($w==3) {
                        array_push($holi1,array(9,$n-1,"国民の休日"));
                }
        }

       $stday = new DateTime($nen.'-'.$month.'-1');
       $stweek = (int)$stday->format('w');  // 1日の曜日
       $days = (int)$stday->format('t'); // 月の日数
       $weeks=array("SUN","MON","TUE","WED","THU","FRI","SAT");
       print "<g transform=\"translate({$bx},{$by})\">\n"; // 月の始まり
        print "<text class=\"mfont c{$color}3\" x=\"12\" y=\"0\">{$nen}年{$month}月</text>\n";
       for($i=0;$i<7;$i++) {
               $x = 25*$i+12;
               $w = $weeks[$i];
               print "<text class=\"wfont c{$color}3\" x=\"{$x}\" y=\"25\">{$w}</text>\n";
       }

        $wn = 0; // 何週目
        $w = $stweek; //スタートの曜日
        $px = 25*$w; // 日のX座標
        $py = 0;     // 日のY座標
        $c = 1;  // 色
        $mess = '';
        $furi = false;
        print "<g transform=\"translate(0,30)\">\n"; // 月の数字の部分の基点
        print "<g transform=\"translate(0,0)\">\n"; // 一週間の基点
        for($i=1;$i<=$days;$i++) {
                if($w==0)
                        $c = 3;
                elseif($w==6)
                        $c = 2;
                else
                        $c = 1;
                if($furi) {     // 振替休日
                        $c = 3;
                        $furi = false;
                        $mess.="{$i}日振替休日 ";
                }
                foreach($holi1 as $h) { // 固定祝日
                        if($h[0]==$month && $h[1]==$i) {
                                $c = 3;
                                if($w==0) $furi=true;
                                $mess.="{$i}日{$h[2]} ";
                        }
                }
                $wn2 = (int)(($i+6)/7);

                foreach($holi2 as $h) { // 月曜日の祝日
                        if($w==1 && $h[0]==$month && $h[1]==$wn2) {
                                $c = 3;
                                $mess.="{$i}日{$h[2]} ";
                        }
                }

                if(23<=$i && $i<=24 && $w<2 && $wn==4 && $i+7 <= $days) {
                        $i2 = $i+7;
                        print <<<LINE2
<g transform="translate({$px},0)"><rect class="c{$color}{$c}" width="22" height="22" rx="4"/>
<text class="dfont2" x="7" y="9">{$i}</text>
<text class="dfont2" x="16" y="20">{$i2}</text>
<line x1="20" y1="2" x2="2" y2="20" stroke="#FFFFFF" stroke-width="1" />
</g>\n
LINE2;
                } else {
                        print <<<LINE1
<g transform="translate({$px},0)"><rect class="c{$color}{$c}" width="22" height="22" rx="4"/>
<text class="dfont" x="12" y="16">{$i}</text></g>\n
LINE1;
                }
                $w++;
                $px += 25;
                if($w>6) {
                        $w = 0;
                        $px = 0;
                        $wn++;
                        if($wn==5) break;
                        $py +=25;
                        print "</g><g transform=\"translate(0,{$py})\">\n";
                }
        }
        print "</g>\n"; //一週間の終わり
        print "</g>\n"; //月の数字の部分の終わり
        if(!empty($mess)) {
                $py = 163;
                print "<text class=\"m3font c{$color}3\" x=\"0\" y=\"{$py}\">{$mess}</text>\n";
        }


       print "</g>\n"; // 月の終わり
}
// Main Program
svgstart();
$px=30;$x=0;
$py=30;
$color=0;
$nen = $_GET['nen']+0;
if($nen==0) $nen=2017;
for($i=1;$i<=12;$i++) {
        svgmonth($nen,$i,$px,$py,$color);
        $color = (++$color)%6;
        $px += 200;$x++;
        if($x==4) {
                $px=30;
                $x=0;
                $py+=195;
        }
}
svgend();