[PHP]ある曜日の第n週は何日か調べる(国民の祝日)

ハッピーマンデー制度により、一部の日本の祝日は月日固定ではなく、曜日で固定して連休になるようにつくられています。

2012年12月現在、月曜日に移動した国民の祝日は以下の4つです

・成人の日(1月の第2月曜日) ・海の日(7月の第3月曜日) ・敬老の日(9月の第3月曜日) ・体育の日(10月の第2月曜日)

たとえば、成人の日は、1月の第2月曜日で、それが何日にあたるかはその年によって異なります。

PHP でこれを調べるには、ある曜日の第1週が何日かを計算し、何週目かによって 7 を足していきます。

<?php
//年
$year = 2038;
 
//名前, 月, 週, 曜日(0~6)の順
$holiday = array(
    array("成人の日", 1, 2, 1),
    array("海の日", 7, 3, 1),
    array("敬老の日", 9, 3, 1),
    array("体育の日", 10, 2, 1)
);

$datetime = new DateTime();
$datetime->setTimezone( new DateTimeZone('Asia/Tokyo') );
 
foreach($holiday as $value){
	list($name, $month, $week, $wday) = $value;
 
    //その月の始まりは何曜日か
	$datetime->setDate($year, $month, 1);
    $w = (int)$datetime->format('w');
 
    //指定された曜日の最初の日
    $first = ($wday - $w >= 0) ? 1 + $wday - $w : 1 + $wday - $w + 7;
 
    //日にちを算出
    $day  = $first + ( 7 * ($week - 1) );
	$datetime->setDate($year, $month, $day);
 
    echo $name . ': ' . $datetime->format('Y-m-d') . "\n";
}

出力結果

成人の日: 2038-01-11
海の日: 2038-07-19
敬老の日: 2038-09-20
体育の日: 2038-10-11

$holiday には「名前, 月, 週, 曜日」の順で指定します。曜日は日曜日が 0 で土曜が 6 です。

[PHP]ある曜日に該当する日だけを表示する

一年の中で、土日のみ抽出して表示したい時などは DateInterval を一日間隔にセットし、曜日をチェックすれば簡単です。
閏年を考慮した日数分ループさせるか、年が変わったらループを抜けるように設計するのがいいと思います。

こちらのサンプルでは配列として日曜(0)と土曜(6)を指定し、該当する日にちを表示します。

<?php
$year   = 2038;
$target = array(0, 6);		// 日曜と土曜

$datetime = new DateTime();
$datetime->setTimezone( new DateTimeZone('Asia/Tokyo') );
$datetime->setDate($year, 1, 1);

// 間隔
$interval =  new DateInterval('P1D');

// 閏年をチェック
$days = $datetime->format('L') == '1' ? 366 : 365;

$result = array();

for($i=0;$i<$days;$i++){
	if( in_array( (int)$datetime->format('w'), $target) ){
		$result[] = clone $datetime;
	}
	$datetime->add($interval);
}

foreach($result as $value){
	echo $value->format("Y-m-d l") . "\n";
}

実行結果

2038-01-02 Saturday
2038-01-03 Sunday
2038-01-09 Saturday
2038-01-10 Sunday
2038-01-16 Saturday
2038-01-17 Sunday
2038-01-23 Saturday
2038-01-24 Sunday
2038-01-30 Saturday
2038-01-31 Sunday
2038-02-06 Saturday
2038-02-07 Sunday
2038-02-13 Saturday
2038-02-14 Sunday
(以下略)

[PHP]閏年かどうか判定する

閏年は基本的に4年に一度ですが、100 で割り切れる年は閏年ではありません。 ただし、400 で割り切れる場合は閏年とするというややこしい法則があります。

if文で「%4==0」などを組み合わせて調べてもいいですが、関数「date(‘L’)」で閏年を簡単に調べられます。

<?php
$year = 2012;
if(date('L', mktime(0,0,0,1,1,$year))){
    echo "閏年です";
}