PHP で固定間隔の時系列を生成する方法

PHP の組み込みの関数を利用して固定間隔のタイムシリーズを取得する方法についてご紹介します。

出力のイメージは次のとおりです。

<?php
[
  '2020年12月',
  '2020年11月',
  '2020年10月',
]

この場合は DatePeriod オブジェクトを使うやり方がシンプルです。

<?php

/**
 * 1 ヶ月間隔で連続した年月を生成する
 */
function get_month_series(DateTime $start, DateTime $stop) {

  $interval = new DateInterval('P1M');
  $monthrange = new DatePeriod($start, $interval, $stop);

  $time_units = [];
  foreach ($monthrange as $m) {
    $value = date('Y年m月', $m->getTimestamp());
    $time_units[] = $value;
  }

  return array_reverse($time_units);
}

テストしてみます。

<?php

$start = new DateTime();
$start->setDate(2020, 10, 1);

$stop = new DateTime();
$stop->setDate(2021, 1, 1);

$months = get_month_series($start, $stop);

var_dump($months);
// => [
//   "2020年12月",
//   "2020年11月",
//   "2020年10月",
// ]

うまく使えています。

ポイントは次のとおりです。

  • DateInterval() のコンストラクタには固有の書式( P1M など)を使う(ちなみに P1M は 1 ヶ月間隔という意味です)。
  • DatePeriod() はネガティブインターバルは受け付けないので、降順の一覧を生成したい場合は昇順に生成したものを array_reverse() でひっくり返す必要がある。

PHP だとこういう処理は手続き型で汚く書いてしまいがちですが、こういうこともできるみたいです。 日付選択のセレクトボックスの生成などに重宝します。