我得到一个包含一年的句号的数组如下。
$year = '2016';
$periods = [
[
'name' => "Name One",
'startDate' => '01/01/2016',
'endDate' => '03/31/2016'
],
[
'name' => "Name Two",
'startDate' => '04/01/2016',
'endDate' => '12/31/2016'
]
];
句点数可能会有所不同,因此,数组句点可能包含任意数量的元素(比如5个元素,表示给定年份的5个句点)。现在我需要确保期间确实构成一年,即两个期间不能重叠,期间总计确定为指定年度。
我尝试了许多不同的方法,但未能提出任何有效的解决方案。 我正在使用Laravel 5,因此使用Carbon包。但即使在Basic PHP中,我也很高兴能够完成这项工作。所以欢迎所有建议
答案 0 :(得分:2)
尝试一下 - 可能有一个更优雅的解决方案,但我认为这是有效的。我使用过Carbon,因为它有一些非常有用的辅助方法。
我假设您的$periods
数组将按日期顺序排列。如果不是,您可以usort
。
$year = '2016';
$periods = [
[
'name' => "Name One",
'startDate' => '01/01/2016',
'endDate' => '03/31/2016'
],
[
'name' => "Name Two",
'startDate' => '04/01/2016',
'endDate' => '12/31/2016'
]
];
// set a start position
$currentPosition = Carbon::create($year, 1, 1)->startOfDay();
// and the end of the year
$endOfYear = Carbon::create($year, 1, 1)->addYear()->startOfDay();
// iterate periods
foreach ($periods as $period) {
$start = Carbon::createFromFormat('m/d/Y', $period['startDate'])->startOfDay();
$end = Carbon::createFromFormat('m/d/Y', $period['endDate'])->endOfDay();
// start of this period should follow the last (??)
if ($start < $currentPosition) {
throw new Exception("$start is earlier than $currentPosition");
}
// must follow on from the current position
if ($currentPosition->diffInDays($start) > 0) {
throw new Exception("$start doesn't follow $currentPosition");
}
// check it doesn't go over the end of the year
if ($currentPosition->addDays($start->diffInDays($end)) > $endOfYear) {
throw new Exception("$end takes us over the end of the year!");
}
$currentPosition = clone $end;
}
// did we reach the end?
if ($currentPosition->addDay()->startOfDay() != $endOfYear) {
throw new Exception("Full year not accounted for");
}
// we're done
echo 'Full year accounted for'.PHP_EOL;