[ PHP ] ある月の第 3 日曜のような条件から日付を導出する

Pocket

ここでは、2011 年 7 月の第2 木曜日のような条件を元にその日付を送出するサンプルコードを計算しています。詳細はサンプル中のコメントを参照ください。

スポンサーリンク

ある月の第N W曜日の日付を求めるサンプル

/*
 * 第n w 曜日の日付を求める
 * @param <integer> $year    年
 * @param <integer> $month   月
 * @param <integer> $no      第 n 週
 * @param <integer> $week    0 (日曜)から 6 (土曜)
 * @return <DateTime>
 */
function getDateFromWeekInfo($year, $month, $no, $week)
{
    // 最初の一週間分の曜日を求める
    // 1日の曜日を求める

    $date = new DateTime();
    /*
     * 以下の記述は PHP 5.3.0 以降で可能
     * それ以前の PHP では setDate が成功した場合は null がリターンされるので、
     * 2行に分けて $date->format('w'); のように記述すること
     */
    // 指定年月の1日の曜日を抽出する
    $first_week = $date->setDate($year, $month, 1)
                       ->format('w'); // 0 (日曜)から 6 (土曜) を取得する

    // 1日の曜日の指定週の日付を求める
    $day = ($no - 1) * 7 + 1;

    // 指定曜日と1日の曜日の差分(日数)を求め、指定の日付を計算する
    $diff = $week - $first_week;
    if($diff < 0) { 
        $day += $diff + 7; // 1日の曜日より前の曜日の場合 
    } else { 
        $day += $diff; // 1日の曜日より後の曜日の場合 
    } 
    // 組み立てた日付が月の最終日(日数)よりも大きい場合は false リターン 
    if($date->format('t') < $day) { return false; } 
    
    // 前述のとおり、PHP 5.3.0 以降での記述 
    return $date->setDate($year, $month, $day);
}

// 2011年 7月の第5月曜日を求める(存在しないので false )
$date = getDateFromWeekInfo(2011, 7, 5, 1);
var_dump($date);
// boolean false

// 2011年 7月の第3月曜日を求める
$date = getDateFromWeekInfo(2011, 7, 3, 1);
var_dump($date);
// object(DateTime)[1]
//   public 'date' => string '2011-07-18 22:06:09' (length=19)
//   public 'timezone_type' => int 3
//   public 'timezone' => string 'Asia/Tokyo' (length=10)

/*
 * ハッピーマンデー
 */
// 成人の日(1月の第2月曜日)
$date = getDateFromWeekInfo(2011, 1, 2, 1);

// 海の日(7月の第3月曜日)
$date = getDateFromWeekInfo(2011, 7, 3, 1);

// 敬老の日(9月の第3月曜日)
$date = getDateFromWeekInfo(2011, 9, 3, 1);

// 体育の日(10月の第2月曜日)
$date = getDateFromWeekInfo(2011, 10, 2, 1);

strtotime 関数を使用する

strtotime 関数を使用して、英文形式の日付からある月の第3日曜日のような日付を求めるサンプルコードです。

// 2011年8月第1土曜日
var_dump(date('Y-m-d', strtotime('first sat of aug 2011')));
// string '2011-08-06' (length=10)

// 2011年8月第2金曜日
var_dump(date('Y-m-d', strtotime('second fri of aug 2011')));
// string '2011-08-12' (length=10)

// 2011年8月第3土曜日
var_dump(date('Y-m-d', strtotime('third sat of aug 2011')));
// string '2011-08-20' (length=10)

// 2011年8月第4土曜日
var_dump(date('Y-m-d', strtotime('fourth sat of aug 2011')));
// string '2011-08-27' (length=10)

// 2011年8月第5土曜日(存在しない)
// 注意:存在しない場合は、次月にまたいで算出される
var_dump(date('Y-m-d', strtotime('fifth sat of aug 2011')));
// string '2011-09-03' (length=10)

// 指定された曜日の月の最終日を求める(例:2011年8月最終木曜日)
var_dump(date('Y-m-d', strtotime('last thu of aug 2011')));
// string '2011-08-25' (length=10)

注意事項:PHP マニュアル – strtotime 関数より抜粋
—————————————————-
5.2.7 より前の PHP 5 では、「ある月の何回目の何曜日」 を取得するときにもしその月の初日が
その曜日だった場合、タイムスタンプが間違って一週間追加されてしまっていました。
これは 5.2.7 以降のバージョンでは修正されています。

先週の日曜、来週の水曜のような条件から日付を求める

strtotime 関数を使用して先週の日曜のような条件から日付を導出するサンプルになります。詳細はコメント参照ください。

/*
 * 今日が2011年8月9日(火)の場合
 */
 
// 先週の火曜日
var_dump(date('Y-m-d', strtotime('tuesday previous week')));
// string '2011-08-02' (length=10)

// 次の火曜日(今日が指定した曜日の場合は当日となる)
var_dump(date('Y-m-d', strtotime('tuesday')));
// string '2011-08-09' (length=10)

// 来週の火曜日
var_dump(date('Y-m-d', strtotime('tuesday next week')));
// string '2011-08-16' (length=10)

// 先週の月曜日
var_dump(date('Y-m-d', strtotime('monday previous week')));
// string '2011-08-01' (length=10)

// 次の月曜日
var_dump(date('Y-m-d', strtotime('monday')));
// string '2011-08-15' (length=10)

// 来週の月曜日
var_dump(date('Y-m-d', strtotime('monday next week')));
// string '2011-08-15' (length=10)
参考
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *