運営者情報

運営してるひと: @sters9

       

妻と猫と横浜あたりに住んでいる。最近は Go や Kubernetes や GCP をしています。 PHP や JavaScript もすこし。

プライバシーポリシー

tools.gomiba.co

アーカイブ

2021/02 (12) 2021/01 (8)

2020/05 (2) 2020/04 (2) 2020/02 (2) 2020/01 (1)

2019/12 (3) 2019/11 (2) 2019/10 (5) 2019/09 (3) 2019/07 (6) 2019/06 (4) 2019/04 (3) 2019/01 (2)

2018/12 (6) 2018/10 (4) 2018/09 (6) 2018/08 (7) 2018/07 (16) 2018/06 (7) 2018/05 (7) 2018/04 (5) 2018/03 (3) 2018/02 (10) 2018/01 (6)

2017/12 (8) 2017/11 (6) 2017/10 (10) 2017/09 (12) 2017/08 (12) 2017/07 (3) 2017/06 (1) 2017/01 (4)

2016/12 (5) 2016/10 (3) 2016/09 (1) 2016/07 (2) 2016/06 (1) 2016/04 (1) 2016/02 (1) 2016/01 (2)

2015/12 (1) 2015/10 (1) 2015/09 (3) 2015/06 (1) 2015/01 (1)

2014/08 (2) 2014/07 (3) 2014/05 (1) 2014/01 (7)

2013/12 (2) 2013/11 (4) 2013/10 (1) 2013/09 (1) 2013/08 (3) 2013/07 (4) 2013/06 (5) 2013/05 (2) 2013/04 (7) 2013/03 (1)

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

この記事は公開されてから1年以上経過しており、情報が古くなっている可能性があります。

日単位のデータがわっとあって、週とか月とかの単位で集計してーなー!みたいな、そういう事をやりたいときってあると思うんですよ。 そのための日付の範囲を一覧にしてくれるやつ、というイメージで。作ったらあとは 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]\
";
}

echo "------\
";

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

echo "------\
";

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

/**
$ 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
*/

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

いじよ。