PHPによる日付・時刻・時間の計算・演算

PHPによる日付・時刻・時間の計算・演算

とある日が今から何日後?
というのをPHPでやるならどうするのがいいんだろう

そんな感じで調べていたらPHP による日付・時刻・時間の計算・演算のまとめ – hoge256ブログを見つけました
これこれ、って思ったけどよくよく見てみるとちょっと情報が古いような、2007年の記事だし・・・

という訳でちょっと書き直してみました

現在時刻の取得

echo date('Y-m-d H:i:s');
$date = new DateTime();
echo $date->format('Y-m-d H:i:s');

日付/時刻のパース

日付/時刻を表したある書式の文字列から、年、月、日、時、分、秒を取得します

echo date('Y-m-d H:i:s', strtotime('2011-08-12 10:35:20'));
$date = new DateTime('2011-08-12 10:35:20');
echo $date->format('Y-m-d H:i:s');

‘Y-m-d H:i:s’の部分を変えれば取得したいものだけ表示できます。
また、’2007-08-12 10:35:20’が’2007/08/12’でも表示可能です

日付の妥当性チェック

指定された日付が有効な日付かどうかをチェックします。

if(checkdate(4, 31, 2011) === false) {
    echo "無効な日付です";
} else {
    echo "有効な日付です";
}
try {
    $date = new DateTime('2011-04-31');
} catch (Exception $e) {
    // 無効な日付な場合
    print_r(DateTime::getLastErrors());

    // オブジェクト指向流にやるなら、本来は
    // echo $e->getMessage();
}

getLastErrors()を使うことはあまりない気がしますが。。

ちなみに↓はエラーは出ず、正しい?日付が出ます。

$date = new DateTime('2011-04-31');
echo $date->format('Y-m-d');
// 2011-05-01

うるう年(閏年)の判定

echo (date('L', strtotime('2000-1-1'))) ? '閏年' : '閏年ではない';
function isLeapYear($year) {
    $date = new DateTime();
    $date->setDate($year, 1, 1);
    return ($date->format('L')) ? true : false;
}

var_dump(isLeapYear(2000)); // true
var_dump(isLeapYear(2011)); // false

n日後、n日前の日付を求める

今日から1週間後は何月何日?とか、10日前は何月何日?みたいな計算を行う場合に使います

echo date('Y-m-d H:i:s', strtotime("+ 7 days"));
// 2011-11-11 23:18:26
echo date('Y-m-d H:i:s', strtotime("- 10 days"));
// 2011-10-22 23:19:24
$date = new DateTime('+7 days');
echo $date->format('Y-m-d H:i:s');
// 2011-11-11 23:18:26
$date = new DateTime('-10 days');
echo $date->format('Y-m-d H:i:s');
// 2011-10-22 23:19:24

任意のn日後、n日前の日付を求める

今日じゃない日からのn日後、n日前の日付を求める場合もほとんど変わりません

echo date('Y-m-d H:i:s', strtotime("2011-08-12 +7 days"));
// 2011-08-19 00:00:00
echo date('Y-m-d H:i:s', strtotime("2011-08-12 -10 days"));
// 2011-08-02 00:00:00
$date = new DateTime('2011-08-12');
$date->modify('+7 days');
echo $date->format('Y-m-d H:i:s');
// 2011-08-19 00:00:00
$date = new DateTime('2011-08-12');
$date->modify('-10 days');
echo $date->format('Y-m-d H:i:s');
// 2011-08-02 00:00:00

任意の年月の月末日を求める

任意年月の月末日を求めます 

echo date('t', strtotime('2011-08-12'));
// 31
function getMonthEndDay($year, $month) {
    $date = new DateTime();
    $date->setDate($year, $month, 1);
    return $date->format('t');
}

echo getMonthEndDay(2011, 8); 
// 31

nヶ月後、nヶ月前の日付を求める

echo date('Y-m-d H:i:s', strtotime("2011-08-12 +1 month"));
// 2011-08-19 00:00:00
echo date('Y-m-d H:i:s', strtotime("2011-01-31 +1 month"));
// 2011-03-03 00:00:00

以前にも話題にした事がありますが、2011-01-31の1ヵ月先が2011-03-03なのはPHP的には仕様だったりします
 

$datetime = new DateTime('2011-01-31');
echo $datetime->add(DateInterval::createFromDateString("1 month"))->format("Y-m-d H:i:s");

以前は仕様で済ましてしまったので考えてみる

<

// $dateの$month後の年月日を出力する
function getPreviousMonth($date, $month) {
    $datetime = new DateTime($date);
    $res      = $datetime->add(DateInterval::createFromDateString("$month month"))
                         ->format('d');

return ($<pre><code>
                      : $datetime->sub(DateInterval::createFromDateString($res . " days"))
                                 ->format('Y-m-d');

}
echo getPreviousMonth('2011-01-31', 1);
// 2011-02-28

※PHP5.3が必要

日付の比較を行う

日付の比較を行います

if (strtotime('2011-08-12') > strtotime('2011-01-12')) {

} else {

}
$d1 = new DateTime('1492-01-01');
$d2 = new DateTime('1492-12-31');

var_dump($d1 < $d2); // bool(true)
var_dump($d1 > $d2); // bool(false)
var_dump($d1 == $d2); // bool(false)

2つの日付の差(何日間あるか)を求める

2つの日付の差を求めます 

echo (strtotime('2009-10-13') - strtotime('2009-10-11')) / ( 60 * 60 * 24);
// 2
$datetime1 = new DateTime('2009-10-11');
$datetime2 = new DateTime('2009-10-13');
$interval = $datetime1->diff($datetime2);
echo $interval->format('%a days');
// 2 days

※PHP5.3以上が必要

誕生日から年齢を求める

上の日付の差を応用すると、誕生日から現在の年齢を簡単に求めることが出来ます

    function getAgeFromBirthday($year, $month, $day) {
        $now = new DateTime();
        $birthday = new DateTime($year.sprintf('%02d', $month). sprintf('%02d', $day));
        $interval = $now->diff($birthday);
        return $interval->y;
    }

※PHP5.3以上が必要

というわけで

便利だし2037年問題にも対応しているDateTime便利!って感じなのでした
もうちょっと真面目にまとめてgistとかに置きたいなぁ・・・