ウェブのあれこれ
ウェブを活用したいひとのためのブログ
PHPで日時計算とフォーマットを簡単に行う方法
2015/01/07 プログラミング

PHPで日時計算とフォーマットを簡単に行う方法

リクエストから取得した日付書式の文字列、あるいはDBから取得した日付書式の文字列。日付書式の文字列を扱うことはよくありますよね。今回はPHP5.3以降に準拠した日付型文字列処理のTIPSをご紹介!

よくある簡単な日付計算の方法

date関数とstrtotime関数

PHPでの日付の扱いは何と言ってもdate関数がとても簡単ですね。

$dataStr = date('フォーマット指定文字列');

さらに、多彩な日付フォーマット指定ができるPHPではstrtotime関数を利用して、直感的に日時の計算が行えます。

$timestampInt = strtotime('2014-Dec-16');
$timestampInt = strtotime('-12 day');

このあたりはWEBを検索しているとさまざまなサイトで出てくるよくあるtipsですね。
関数を利用してごく簡単に実装できるため、一般的なやり方となっているようです。

実はPHPは他のやり方を推奨している!?

「PHP 日付計算」などと検索するとほとんどの上記のようなやり方をしているサイトが結構出てきますよね。しかし!PHPマニュアルを読んでいると以下のような一文が!

この関数を使って日付の足し算や引き算を行うことはおすすめできません。 PHP 5.3 以降なら DateTime::add() や DateTime::sub() を、そして PHP 5.2 なら DateTime::modify() を使いましょう。

なんということでしょう、現在PHPの公式マニュアルではstrtotime関数によるタイムスタンプの変換を推奨していません。代わりにDateTimeクラスを利用することをお勧めしています。

明確な理由はわかりませんが、おそらく2038年問題に対応するための勧告だと思われます。一応64bit版ならば事実上無制限に日付を扱えるはずですが、日時を扱うクラスを用意したんだからそっち使ってよってことですかね。

PHPマニュアル推奨の日時計算とフォーマット

というわけで、推奨されたやり方で、日時計算とフォーマットを行う方法をご紹介しましょう。
今回はPHP5.3以上で推奨されている、DateTime::add() と DateTime::sub()を紹介します。

DateTimeオブジェクト

まずは基本となるDateTimeオブジェクト。(クラスリファレンス:http://php.net/manual/ja/class.datetime.php)
名前の通り、日時を扱うためのクラスです。

try {
$date = new DateTime('2000-01-01');
} catch (Exception $e) {
echo $e->getMessage();
}

作成方法は初期化パラメータに日付型書式の文字列を与えるだけです。
日付型書式はstrtotime関数同様、日付と時刻の書式を利用できます。
サンプルでtry~catchで囲んでいるのはPHP5.3以降で日付書式が不正な場合に例外が発生するためです。

DateTime::add()とDateTime::sub()による日時計算

日時の加算にはDateTime::add()メソッドを利用します。
strtotime関数の時には相対書式の文字列が引数でしたが、DateTime::add()メソッド引数がDateInterval型のオブジェクトとなっている点に注意が必要です。

try {
$date = new DateTime('2000-01-01');
$date->add(new DateInterval('P10D'));
} catch (Exception $e) {
echo $e->getMessage();
}

このDateIntervalクラスの初期化パラメータはISO 8601 duration specificationに基づくフォーマットで指定する必要があるのですが、いまいち直感的ではありません。
そこで、DateInterval::createFromDateString()メソッドを利用して相対書式からDateIntervalオブジェクトを生成することができます。

try {
$date = new DateTime('2000-01-01');
$date->add(DateInterval::createFromDateString('1 day'));
} catch (Exception $e) {
echo $e->getMessage();
}

これで使用感的にはstrtotime関数と同じ指定ができます。

DateTime::sub()も利用方法は同じで引数にDateIntervalオブジェクトを指定して、日時の減算を行います。

try {
$date = new DateTime('2000-01-01');
$date->sub(DateInterval::createFromDateString('1 day'));
} catch (Exception $e) {
echo $e->getMessage();
}

DateTime::format()による日時のフォーマット

日時のフォーマットを行うDateTime::format()メソッドの引数はdate関数と同じ書式指定を与えることでフォーマットされた文字列を返却します。

try {
$date = new DateTime('2000-01-01');
echo $date->format('Y年m月d日');
} catch (Exception $e) {
echo $e->getMessage();
}

date関数と同じ引数を設定するだけなので使用感は変わりませんね。

計算とフォーマットを行う関数にする

最後に、そのまま使うと毎回オブジェクトが必要になるので計算とフォーマットを行う関数にしてしまいましょう。

function dateFormat($date, $format, $calc='now', $type='add')
{
$formated = '';
try {
$dateObj = new DateTime($date);
$interval = DateInterval::createFromDateString($calc);
switch($type)
{
case 'sub':
$dateObj->sub($interval);
break;
case 'add':
default:
$dateObj->add($interval);
break;
}

$formated = $dateObj->format($format);

} catch (Exception $e) {
$formated = 'ERROR';
}

return $formated;
}

これで、フォーマットと計算を行える関数が出来上がりました。

サポートされている書式指定や相対書式はPHPのマニュアルで詳しく説明されているので、熟知すればさまざまな日付処理が簡単に行えますね!



Provided by Revolme inc.
revolme.co.jp