LoginSignup
0
0

More than 1 year has passed since last update.

PHPで日本の祝日付きカレンダーを作る

Last updated at Posted at 2021-11-18

CarbonとYasumiを使います

CarbonはLaravelに入ってるので直観的に扱える人は多いかなと。

インストール

composerで導入します。

Carbon

Yasumi

サンプル

以下のようなDirで配置

html/index.php
html/vender/...

サンプルコード(折り畳み)
index.php
<?php
ini_set('display_errors', "On");
ini_set('error_reporting', E_ALL);
require 'vendor/autoload.php';

use Yasumi\Yasumi;
use Carbon\Carbon;
use HtmlPrinter as HP;
date_default_timezone_set('Asia/Tokyo');

?><!DOCTYPE html>
<html lang="ja" class="no-js">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width">

  <title>sample</title>

<!-- reset.css ress -->
<link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
</head>
<body>
<table>

</table>
<?php
HP::pp(Carbon::now());
HP::pp(Carbon::now()->startOfMonth()->toDateString() . "->" . Carbon::now()->endOfMonth()->toDateString());

$startMonth = Carbon::now()->subMonth(Carbon::now()->month);
for($i = 0;$i < 12; $i++){
        CalenderBuilder::makeCalendar($startMonth->addMonth());
}

?>
</body>
</html><?php
class CalenderBuilder{
        public static function makeCalendar(Carbon $carbon = null){
                //初期化
                $c = is_null($carbon) ? Carbon::now() : $carbon->copy();
                $ysm = Yasumi::create('Japan',$c->year,'ja_JP');
                HP::pp($c->format('Y年m月'));
                //月初はその週の日曜日まで前月の日にちを補完
                $som = $c->copy()->startOfMonth()->subDay($c->copy()->startOfMonth()->dayOfWeek);
                //月末は翌月の土曜日まで補完
                $eom = $c->copy()->endOfMonth()->addDay(6 - $c->copy()->endOfMonth()->dayOfWeek);

                for ($sd = $som->copy(); $sd < $eom ; $sd->addDay()) {
                        if($ysm->isHoliday($sd)){
                                HP::pnr($sd->format('d日'), $ysm->getHoliday(array_search($sd->format('Y-m-d'),$ysm->getHolidayDates()))->getName());
                        }else{
                                HP::pn($sd->format('d日'));
                        }
                        if($sd->isSaturday()){
                                echo '<br>';
                        }
                }
        }
}
class HtmlPrinter{
        private CONST ECHO_DEBUG = true;
        public static function pnr(string $p,string $title = ''):void{
                if(!static::ECHO_DEBUG)return;
                echo '<span title="'.htmlspecialchars($title).'" style="color:red ;">'. htmlspecialchars($p,ENT_QUOTES|ENT_SUBSTITUTE) . "</span>\n";
        }
        public static function pn(string $p):void{
                if(!static::ECHO_DEBUG)return;
                echo "<span>". htmlspecialchars($p,ENT_QUOTES|ENT_SUBSTITUTE) . "</span>\n";
        }
        public static function pp(string $p):void{
                if(!static::ECHO_DEBUG)return;
                echo "<p>". htmlspecialchars($p,ENT_QUOTES|ENT_SUBSTITUTE) . "</p>\n";
        }
        public static function pt(string $p):void{
                if(!static::ECHO_DEBUG)return;
                echo "<pre>". htmlspecialchars($p,ENT_QUOTES|ENT_SUBSTITUTE) . "</pre>\n";
        }
}

image.png

1か月を前月と翌月で補完して12か月分表示し
休日に色を付けてマウスカーソルを合わせると休日の名前が出るようになった

その休日の名前を取得する時癖のあるYasumi

基本的にYasumiはインスタンスを生成するときに年を指定してその年の休日一覧を取得する

$ysm = Yasumi::create('Japan',$c->year,'ja_JP');
foreach($ysm as $holiday) {
        HP::pp($holiday . ':' . $holiday->getName());
}

image.png

よってその日の休日名を取得するときはかなり遠回りをする

$holidays = Yasumi::create('Japan',2021,'ja_JP');
foreach($holidays as $v){
        $ysmDays[$v->__toString()]=$v->getName();
}
echo $ysmDays['2021-01-01'];
//元日

結果的に年に依存しており、依存性を解消するため
サンプル内では以下のように取得している

$c = is_null($carbon) ? Carbon::now() : $carbon->copy();
$ysm = Yasumi::create('Japan',$c->year,'ja_JP');
if($ysm->isHoliday($sd)){
   HP::pnr($sd->format('d日'), $ysm->getHoliday(array_search($sd->format('Y-m-d'),$ysm->getHolidayDates()))->getName());
}

軽くソースを読むと
https://github.com/azuyalabs/yasumi/tree/develop/src/Yasumi
感覚的にはYasumi->onでDateTimeを渡し
OnFilterで休日であればその祝日のHolidayを返せばいいと思うのだが
Testとか面倒なのでライブラリへのプルリクやめてごり押し実装した。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0