darudaru

だるだるしてるエンジニア

DateTimeImmutableで日時を扱う

DateTimeImmutableクラス

  • PHP5.5以上から使える
  • DateTimeは参照渡しなので自身のオブジェクトが変わっていくが、DateTimeImmutableは新しいオブジェクトを返す
  • モダンなやり方だって聞いた

使い方

現在の日時を取得する

<?php
$date = new DateTimeImmutable();
echo $date->format('Y/m/d H:i:s');  // 2017/04/30 15:41:09 

format()に渡す書式は、date()で指定できる書式が使えます。
詳しくは、PHP: date - Manualを参照。

任意の日時を取得する

数値から
<?php
$date = new DateTimeImmutable();
// 年月日で作成する
echo $date->setDate('2017', '5', '5')->format('Y/m/d H:i:s');  // 2017/05/05 19:34:16
// 年月日+時間で作成する
echo $date->setDate('2017', '5', '5')->setTime('8', '15', '30')->format('Y/m/d H:i:s');  // 2017/05/05 08:15:30
YYYY-mm-dd のような書式から
<?php 
$date = new DateTimeImmutable('2017-05-05 12:00:00');                                                                                  
echo $date->format('Y/m/d H:i:s'); // 2017/05/05 12:00:00 

DateTimeImmutable()に渡す日時の書式は、PHP: サポートする日付と時刻の書式 - Manualを参照。

YYYY年mm月dd日のような書式から
<?php
$date = DateTimeImmutable::createFromFormat('Y年m月d日 H時i分s秒', '2017年04月29日 19時00分00秒');
echo $date->format('Y/m/d H:i:s');  // 2017/04/29 19:00:00 

createFromFormat()を使うと、自由な書式でDateTimeImmutableオブジェクトを作成できるようになります。

任意の日時を基準にして、相対的な日時を取得する

<?php
$date = new DateTimeImmutable('2017-05-05 10:00:00');
echo $date->modify('yesterday')->format('Y/m/d H:i:s'); // 昨日の00:00:00
echo $date->modify('tomorrow')->format('Y/m/d H:i:s'); // 明日の00:00:00
echo $date->modify('noon')->format('Y/m/d H:i:s'); // 時刻が12:00:00
echo $date->modify('first day of this month')->format('Y/m/d H:i:s'); // 当月1日
echo $date->modify('last day of this month')->format('Y/m/d H:i:s'); // 当月末
echo $date->modify('first day of last month')->format('Y/m/d H:i:s'); // 先月1日
echo $date->modify('last day of next month')->format('Y/m/d H:i:s'); // 来月末
echo $date->modify('-1 weeks')->format('Y/m/d H:i:s'); // 1週間前
echo $date->modify('3 days ago')->format('Y/m/d H:i:s'); // 3日前
echo $date->modify('Monday next week')->format('Y/m/d H:i:s'); // 来週の月曜日  

modify()に指定する書式は、PHP: 相対的な書式 - Manualを参照。

日付の差を取得する

<?php
$date1 = new DateTimeImmutable('2017-05-05 12:00:00');
$date2 = new DateTimeImmutable('2017-06-05 12:00:00');
$diff = $date2->diff($date1);
echo $diff->format('%R%a日');  // -31日

diff()は、ふたつの DateTimeImmutable オブジェクトの差をDateIntervalオブジェクトで返す。
format()に渡す書式は、PHP: DateInterval::format - Manualを参照。

2つの日付の期間の間で何か処理する

<?php
$date1 = new DateTimeImmutable('2017-05-05 12:00:00');
$date2 = new DateTimeImmutable('2017-06-05 12:00:00');
$diff = $date2->diff($date1);

$interval = new DateInterval('P1D'); // どの単位で期間を出すかを指定する
$daterange = new DatePeriod($date1, $interval ,$date2);

foreach($daterange as $date){
    echo $date->format("Ymd"); 
}

DateInterval()に、どれくらいの単位で期間を出したいかを指定します。
指定する書式は、Pを最初につけます。periodのPです。
時間を含む場合は、時間部分の前に文字 T を入れます。

例えば「P1D」だと1日単位、「PT2S」 だと 2 秒単位になります。
詳しい書式は、PHP: DateInterval::__construct - Manualを参照。

まとめ

以上のものを組み合わせれば大抵のことはできるはず。
日付を扱う処理は自力でやると絶対にバグが起きる(確信)ので、素直に標準のクラスを使ったほうがいいと思います。