<?php
/**
* 手作りカレンダークラス
*/
class calendar{
// 本日の情報
public $today = array();
// 表示するカレンダーの情報
public $disp = array();
// 日曜始まりデフォルト
public $startWeek = 0;
/**
* インスタンス化されたときに実行される
*/
public function __constract(){
}
/**
* メンバ変数を初期化する
*/
public function init(){
self::setStartWeek();
self::setToday();
self::setDisp();
}
/**
* HTMLに出力する処理
*/
public function echoAll(){
$echos = array();
$echos[] = self::getTable();
$echos[] = self::getTitleTr();
$echos[] = self::getBeforeTrTd();
for($day=1;$day<32;$day++){
$d = str_pad($day, 2, '0', STR_PAD_LEFT);
if(checkdate($this->disp['m'], $d, $this->disp['Y']) === false){
break;
}
$ts = strtotime($this->disp['Y'].$this->disp['m'].$d);
$week = self::getWeek($ts);
$echos[] = self::getTr($week);
$echos[] = self::getTd($week);
$echos[] = $day;
$echos[] = self::getTdClose();
$echos[] = self::getTrClose($week);
}
$echos[] = self::getAfterTrTd($ts);
$echos[] = self::getTableClose();
return implode('',$echos);
}
public function setStartWeek(){
if (isset($_REQUEST['sw']) && in_array($_REQUEST['sw'],array('1','0'))) {
// 0 : 日曜始まり, 1 : 月曜始まり
$this->startWeek = (int) $_REQUEST['sw'];
}
}
/**
* HTMLに出力する年、月を決定している
*/
public function setDisp(){
if (isset($_REQUEST['ym']) && strlen($_REQUEST['ym']) === 6 && is_numeric($_REQUEST['ym'])) {
$this->disp['Y'] = substr($_REQUEST['ym'], 0,4);
$this->disp['m'] = substr($_REQUEST['ym'], 4,2);
$this->disp['n'] = $this->disp['m']+0;
} else if (isset($this->today['Y'],$this->today['m'])) {
$this->disp['Y'] = $this->today['Y'];
$this->disp['m'] = $this->today['m'];
$this->disp['n'] = $this->disp['m']+0;
} else {
$this->disp['Y'] = date('Y');
$this->disp['m'] = date('m');
$this->disp['n'] = date('n');
}
$this->disp['ts'] = strtotime($this->disp['Y'].$this->disp['m'].$this->today['d']);
}
public function setToday(){
$this->today['Y'] = date('Y');
$this->today['m'] = date('m');
$this->today['d'] = date('d');
$this->today['n'] = date('n');
$this->today['j'] = date('j');
$this->today['ts'] = strtotime($this->today['Y'].$this->today['m'].$this->today['d']);
}
function getWeek($ts){
// 0 (日曜)から 6 (土曜)
return (int) date('w',$ts);
}
function getTable(){
return '<table class="table table-sm table-bordered table-calendar">';
}
function getTableClose(){
return '</table>';
}
function getTitleTr(){
$weeks = array('月', '火', '水', '木', '金', '土', '日');
if ($this->startWeek === 0) {
$weeks = array('日', '月', '火', '水', '木', '金', '土');
}
$return = '<tr class="calendar-title">';
foreach ($weeks as $i => $week){
$return .= self::getTd(($i+$this->startWeek === 7 ? 0 : $i+$this->startWeek));
$return .= $week;
$return .= self::getTdClose();
}
$return .= '</tr>';
return $return;
}
function getBeforeTrTd(){
$firstWeek = self::getWeek(strtotime($this->disp['Y'].$this->disp['m'].'01'));
if ($firstWeek === $this->startWeek) {
// 1日が左端からピッタリ埋まっていれば何もしない
return '';
}
if ($this->startWeek === 0) {
// 日曜始まり
// あと何個 td が必要か
$endI = $firstWeek;
} else {
// 月曜始まり
// あと何個 td が必要か
$endI = $firstWeek - 1;
if ($firstWeek === 0) {
$endI = 6;
}
}
$return = '<tr>';
// その月の1日がくるまでtdを埋める
for($i=0;$i<$endI;$i++){
$return .= self::getTd($i+$this->startWeek);
$return .= ' ';
$return .= self::getTdClose();
}
return $return;
}
function getAfterTrTd($lastTs){
$lastWeek = self::getWeek($lastTs);
if ($this->startWeek === 0) {
// 日曜始まり
if ($lastWeek === 6) {
// 末日が右端までピッタリ埋まっていれば何もしない
return '';
}
// あと何個 td が必要か
$endI = 6 - $lastWeek;
} else {
// 月曜始まり
if ($lastWeek === 0) {
// 末日が右端までピッタリ埋まっていれば何もしない
return '';
}
// あと何個 td が必要か
$endI = 7 - $lastWeek;
}
$return = '';
// その月の末日がくるまでtdを埋める
for($i=1;$i<=$endI && $i<7;$i++){
$return .= self::getTd($i+$lastWeek === 7 ? 0 : $i+$lastWeek);
$return .= ' ';
$return .= self::getTdClose();
}
$return .= '</tr>';
return $return;
}
function getTd($week){
if ($week === 6) {
return '<td class="sat">';
}
if ($week === 0) {
return '<td class="sun">';
}
return '<td>';
}
function getTdClose(){
return '</td>';
}
function getTr($week){
if ($week === $this->startWeek) {
return '<tr>';
}
return '';
}
function getTrClose($week){
if ($this->startWeek === 0) {
// 日曜始まり
if ($week === 6) {
return '</tr>';
}
} else {
// 月曜始まり
if ($week === 0) {
return '</tr>';
}
}
return '';
}
/**
* リンクを作成する。
*/
function getNextLink(){
// 次のページで現在表示されている年月の翌月を表示するためのリンク先のURLパラメータ
return 'ym='.date('Ym',strtotime($this->disp['Y'].$this->disp['m'].'01 + 1month'));
}
/**
* リンクを作成する
*/
function getPreLink(){
// 次のページで現在表示されている年月の前月を表示するためのリンク先のURLパラメータ
return 'ym='.date('Ym',strtotime($this->disp['Y'].$this->disp['m'].'01 - 1month'));
}
}
$c = new calendar();
$c->init();
?>
<div class="row text-center mb-3">
<div class="col-4">
<a href="?sw=<?php echo $c->startWeek;?>&<?php echo $c->getPreLink();?>" class="btn btn-sm btn-outline-primary">前の月</a>
</div>
<div class="col-4 year-month">
<?php echo $c->disp['Y'];?>年<?php echo $c->disp['n'];?>月
</div>
<div class="col-4">
<a href="?sw=<?php echo $c->startWeek;?>&<?php echo $c->getNextLink();?>" class="btn btn-sm btn-outline-primary">次の月</a>
</div>
</div>
<div><?php echo $c->echoAll();?></div>
<div class="row">
<div class="col-12 text-right">
<a href="?sw=<?php echo $c->startWeek === 1 ? '0' : '1';?>&<?php echo $c->getNextLink();?>" class="btn btn-sm btn-outline-secondary"><?php echo $c->startWeek === 1 ? '日曜始まり表示' : '月曜始まり表示切り替え' ?></a>
</div>
</div>