DateTimeについてのメモ : PHP

Pocket

DateTimeクラスのメモです。PHP5.5以降はDateTimeImmutableを使うのが良いですが公式マニュアルにもあるようにImuutableな点を除いて挙動はDateTimeと同じです「このクラスの挙動は DateTime とほぼ同じですが、 自分自身は変更せずに新しいオブジェクトを返すという点だけが異なります。」。

タイムゾーン

タイムゾーンを設定せず日付処理を行うとエラー・不具合の原因となります。

スクリプトで設定

date_default_timezone_set('Asia/Tokyo')

php.iniで設定

date.timezone = Asia/Tokyo

PHP: サポートされるタイムゾーンのリスト – Manual

上記でタイムゾーンを指定すればDateTime関数タイムゾーンが省略されたとき指定したタイムゾーンを使います。以下のサンプルでは未設定を考慮してDateTimeオブジェクトをタイムゾーンを指定して作成しています。

DateTimeの基本的例

$dateTime = new DateTime('now', new DateTimeZone('Asia/Tokyo'));   // nowが2017年1月1日 23時59分59秒のとき 
echo $dateTime->format('Y-m-d: H:i:s');                            // 2017-01-01: 23:59:59

DateTimeの日付処理例

メソッド 意味
public DateTime DateTime::add ( DateInterval $interval ) 「指定した DateInterval オブジェクトを、 指定した DateTime オブジェクトに加えます。」PHP公式マニュアル。
public DateTime DateTime::sub ( DateInterval $interval ) 「指定した DateInterval オブジェクトを、 指定した DateTime オブジェクトから引きます。」PHP公式マニュアル。
public DateInterval DateTime::diff ( DateTimeInterface $datetime2 [, bool $absolute = false ] ) 「ふたつの DateTime オブジェクトの差を返す」PHP公式マニュアル。
$dateTime = new DateTime('now', new DateTimeZone('Asia/Tokyo'));   // nowが2017年1月1日 23時59分59秒のとき 
echo $dateTime->format('Y-m-d: H:i:s');                            // 2017-01-01: 23:59:59

formatメソッドへ指定可能な値はdate()が理解できる書式指定文字列です。  

日付の書式文字列は下記に記載されています。
日付の書式文字列

DateInterval

日付の間隔を表すクラスです。
コンストラクタまたは静的メソッドDateInterval::createFromDateStringで作成します。

メソッド 意味
public DateInterval::__construct ( string $interval_spec ) 「新しい DateInterval オブジェクトを作成する」PHP公式マニュアル。
間隔指示子文字列から作成。
public static DateInterval createFromDateString ( string $time ) 「相対指定文字列から DateInterval を作成する」PHP公式マニュアル。
相対指定文字列から作成。

間隔指示子

最初は P から始まります。これは “period” を表します。 間隔の単位は、整数値の後に間隔指示子をつけて表します。 時間の要素を含む場合は、時間部分の前に文字 T を入れます。

相対指定文字列は下記リンクを参照してください。
PHP: 相対的な書式 – Manual

DateIntervalの例
PHP公式マニュアルから引用

// セットになっているふたつは、それぞれ同じ間隔を表します。
$i = new DateInterval('P1D');
$i = DateInterval::createFromDateString('1 day');

$i = new DateInterval('P2W');
$i = DateInterval::createFromDateString('2 weeks');

$i = new DateInterval('P3M');
$i = DateInterval::createFromDateString('3 months');

DateIntervalを使用した日付操作

例1

$dateTime = new DateTime('2017-01-01 23:59:59', new DateTimeZone('Asia/Tokyo'));   // 2017年1月1日 23時59分59秒でオブエクト作成 
echo $dateTime->format('Y-m-d: H:i:s') . PHP_EOL;                                  // 2017-01-01: 23:59:59
$dateTime->add(new \DateInterval('P3D'));                                          // 3日プラス
echo $dateTime->format('Y-m-d: H:i:s') . PHP_EOL;                                  // 2017-01-04: 23:59:59

例2

$dateTime = new DateTime('2017-01-01 23:59:59', new DateTimeZone('Asia/Tokyo'));   // 2017年1月1日 23時59分59秒でオブエクト作成 
echo $dateTime->format('Y-m-d: H:i:s') . PHP_EOL;                                  // 2017-01-01: 23:59:59
$dateTime->add(new \DateInterval('PT5H'));                                         // 5分プラス 時間の前にTを付ける
echo $dateTime->format('Y-m-d: H:i:s') . PHP_EOL;                                  // 2017-01-02: 04:59:59

最初は P から始まります。これは “period” を表します。 間隔の単位は、整数値の後に間隔指示子をつけて表します。 時間の要素を含む場合は、時間部分の前に文字 T を入れます。

PHP: DateInterval::__construct – Manual

DatePeriod

DatePeriodで10日後までの日付取得するサンプルです。

  • コンストラクタの第3パラメーターへ終了日(DateTimeオブジェクト)を指定したときは終了日は含まれません。
  • コンストラクタの第3パラメーターへ反復回数(整数)を指定したときは終了日に含まれます。
  • コンストラクタの第4パラメーターでDatePeriod::EXCLUDE_START_DATEを指定したときは開始日を含みません。
$stratDate = new \DateTime('2016-01-01', new \DateTimeZone('Asia/Tokyo'));  // 現在時刻でDateTimeインスタンス作成
$endDate   = new \DateTime('2016-01-01', new \DateTimeZone('Asia/Tokyo'));
$endDate->add(new DateInterval('P10D'));                                    // 10日プラス。 2016-01-11。
$dateInterval = new \DateInterval('P1D');                                   // 1日のインターバル作成

// 終了日を含まず10日表示。
$dates = new \DatePeriod($startDate, $dateInterval, $endDate);  
// $datesはDatePeriodのインスタンスです。DatePeriodはTravesableインターフェースを実装しています。
foreach ($dates as $date) {
    // $dはDateTimeクラスのインスタンス
    echo $date->format("Y-m-d") . '<br>';  // 2016-01-02 〜 2016-01-10まで9日間表示
}
$startDate    = new \DateTime('2016-01-01', new \DateTimeZone('Asia/Tokyo')); // 現在時刻でDateTimeインスタンス作成
$dateInterval = new \DateInterval('P1D');                                     // 1日のインターバル作成

// 終了日を含め合計11日表示。
$dates = new \DatePeriod($startDate, $dateInterval, 10); 
foreach ($dates as $date) {
    echo $date->format("Y-m-d") . '<br>';  // 2016-01-02 〜 2016-01-11まで10日間表示
}

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。