Carbon を使って 開始日と終了日を指定した // 単位の日付データ列を生成する

日単位のデータがわっとあって、週とか月とかの単位で集計してーなー!みたいな、そういう事をやりたいときってあると思うんですよ。
そのための日付の範囲を一覧にしてくれるやつ、というイメージで。作ったらあとは SQL とかそれに準ずる何かにポイポイしたらいいと思う。

Laravel の気持ちだったので Carbon だけど Chronos でも同じようにいけると思う。 startOfMonth とかで、自身の日付変わるところは結構驚いた、さすが Carbon やりますねぇ!(

<?php
require_once('vendor/autoload.php');

use Carbon\Carbon;

// 週の最初を日曜日、最後を土曜日に設定
Carbon::setWeekStartsAt(Carbon::SUNDAY); 
Carbon::setWeekEndsAt(Carbon::SATURDAY);

// $type = 1, 2, 3 // day, week, month
function dateRangeIterator($startDate, $endDate, $type=2) {
	$startDate = Carbon::parse($startDate)->startOfDay();
	$endDate = Carbon::parse($endDate)->endOfDay();

	while ($endDate > $startDate) {
		// "この" 始まりと終わりを取得する
		if ($type === 1) {
			$thisStartDay = $startDate->copy();
			$thisEndDay = $thisStartDay->copy()->endOfDay();
		} elseif ($type === 2) {
			$thisStartDay = $startDate->copy();
			$thisEndDay = $thisStartDay->copy()->endOfWeek();
		} elseif ($type === 3) {
			$thisStartDay = $startDate->copy();
			$thisEndDay = $thisStartDay->copy()->endOfMonth();
		}

		// 終わりが指定値を超えないように調整
		if ($thisEndDay > $endDate) {
			$thisEndDay = $endDate;
		}

		// ジェネレーター生成
		yield [$thisStartDay, $thisEndDay];

		// 次の日/週/月にいく
		if ($type === 1) {
			$startDate->startOfDay();
			$startDate->addDays(1);
		} elseif ($type === 2) {
			$startDate->startOfWeek();
			$startDate->addWeeks(1);
		} elseif ($type === 3) {
			$startDate->startOfMonth();
			$startDate->addMonths(1);
		}
	}
}


// 月単位 2/2 ~ 3/2 まで
foreach(dateRangeIterator('2018-02-02', '2018-03-02', 3) as $x) {
	echo "$x[0] - $x[1]\n";
}

echo "------\n";

// 週単位 2/3 ~ 2/18 まで
foreach(dateRangeIterator('2018-02-03', '2018-02-18') as $x) {
	echo "$x[0] - $x[1]\n";
}

echo "------\n";

// 月単位 2/2 ~ 10/12 まで
foreach(dateRangeIterator('2018-02-02', '2018-10-12', 3) as $x) {
	echo "$x[0] - $x[1]\n";
}

/**
$ php hoge.php
2018-02-02 00:00:00 - 2018-02-28 23:59:59
2018-03-01 00:00:00 - 2018-03-02 23:59:59
------
2018-02-03 00:00:00 - 2018-02-03 23:59:59
2018-02-04 00:00:00 - 2018-02-10 23:59:59
2018-02-11 00:00:00 - 2018-02-17 23:59:59
2018-02-18 00:00:00 - 2018-02-18 23:59:59
------
2018-02-02 00:00:00 - 2018-02-28 23:59:59
2018-03-01 00:00:00 - 2018-03-31 23:59:59
2018-04-01 00:00:00 - 2018-04-30 23:59:59
2018-05-01 00:00:00 - 2018-05-31 23:59:59
2018-06-01 00:00:00 - 2018-06-30 23:59:59
2018-07-01 00:00:00 - 2018-07-31 23:59:59
2018-08-01 00:00:00 - 2018-08-31 23:59:59
2018-09-01 00:00:00 - 2018-09-30 23:59:59
2018-10-01 00:00:00 - 2018-10-12 23:59:59
*/

時間とか分とか、単位をもっと細かくしたいんだよね~~ってなっても、同様にして細かい単位のものを実装したらいいと思う。

いじよ。

前後の記事

Next:
Prev: