Skip to content

Instantly share code, notes, and snippets.

@madeindjs
Created May 31, 2017 07:12
Show Gist options
  • Save madeindjs/28fa1e4057aba90ee34ee8718aa0c29d to your computer and use it in GitHub Desktop.
Save madeindjs/28fa1e4057aba90ee34ee8718aa0c29d to your computer and use it in GitHub Desktop.
Slice a given periods into multiples periods cut on months
<?php
/**
* Slice a given periods into multiples periods cut on months
*
* Example: 15/01 - 15/02 = 15/01 - 31/01 : 01/02 - 15/02
*
* @param DateTime $start
* @param DateTime $end
* @yield array whith keys `start` & `end` containing `DateTime` formated
*/
function cutPeriodBetweenMonths(DateTime $start, DateTime $end)
{
while ($start < $end) {
// get the last month of the `$start` date (`Y-m-t` return the last day)
$endMonth = DateTime::createFromFormat('Y-m-d', $start->format('Y-m-t'));
if ($endMonth < $end) {
// get the first month of previous week
$startMonth = clone $endMonth;
$startMonth->add(new DateInterval('P1D'));
yield [
'start' => $start->format('Y-m-d'),
'end' => $endMonth->format('Y-m-d'),
];
$start = $startMonth;
} else {
yield [
'start' => $start->format('Y-m-d'),
'end' => $end->format('Y-m-d'),
];
break;
}
}
}
// Usage example
$start = DateTime::createFromFormat('Y-m-d', '2017-01-15');
$end = DateTime::createFromFormat('Y-m-d', '2017-05-15');
$periods = cutPeriodBetweenMonths($start, $end);
var_export(iterator_to_array($periods));
//[
// 0 => [
// 'start' => '2017-01-15',
// 'end' => '2017-01-31',
// ],
// 1 => [
// 'start' => '2017-02-01',
// 'end' => '2017-02-28',
// ],
// 2 => [
// 'start' => '2017-03-01',
// 'end' => '2017-03-31',
// ],
// 3 => [
// 'start' => '2017-04-01',
// 'end' => '2017-04-30',
// ],
// 4 => [
// 'start' => '2017-05-01',
// 'end' => '2017-05-15',
// ],
//]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment