Skip to content

Instantly share code, notes, and snippets.

@itorgov
Last active March 6, 2020 10:29
Show Gist options
  • Select an option

  • Save itorgov/fdeb793d5612fc859a0b3b1c72f85d6c to your computer and use it in GitHub Desktop.

Select an option

Save itorgov/fdeb793d5612fc859a0b3b1c72f85d6c to your computer and use it in GitHub Desktop.
Divide date interval to subintervals.
<?php
class DateService
{
const SEVEN_DAYS_INTERVAL = 'P7D';
/**
* Метод из начальной и конечной дат делает массив с интервалами заданного размера.
* TODO: Текущий алгоритм мне не очень нравится, но пока что только так придумал.
*
* @param DateTime $startDate Начальная дата.
* @param DateTime $endDate Конечная дата.
* @param string $intervalSize Размер интервалов (используйте константы).
* @return array
*/
public static function getSubIntervals(DateTime $startDate, DateTime $endDate, $intervalSize) {
$dateInterval = new DateInterval($intervalSize);
$dateRange = new DatePeriod($startDate, $dateInterval, $endDate);
$dates = [];
$isFirst = true;
/** @var DateTime $date */
foreach ($dateRange as $date) {
if ($isFirst) {
$dates[] = $date;
$isFirst = false;
continue;
}
$previousDate = clone($date);
$previousDate->modify('-1 day');
$dates[] = $previousDate;
$dates[] = $date;
}
if (end($dates) < $endDate) {
$dates[] = $endDate;
}
$subIntervals = [];
$index = 0;
foreach ($dates as $date) {
if (!isset($subIntervals[$index])) {
$subIntervals[$index] = [];
}
if (!array_key_exists('start', $subIntervals[$index])) {
$subIntervals[$index]['start'] = $date;
} else {
$subIntervals[$index]['end'] = $date;
$index++;
}
}
return $subIntervals;
}
}
@itorgov
Copy link
Author

itorgov commented Aug 25, 2016

Example output of this method. For example, you have an interval with start 2016-08-01 and end 2016-08-31. Then you want to divide it to subintervals and every subinterval have to have 7 days in length. So, we can use constant ONE_WEEK_INTERVAL for that. Final, we will get this array which will contain start and end dates of every subinterval (note that in example below dates are strings, but method returns dates in DateTime objects):

[
    [
        'start' => '2016-08-01',
        'end' => '2016-08-07'
    ],
    [
        'start' => '2016-08-08',
        'end' => '2016-08-14'
    ],
    [
        'start' => '2016-08-15',
        'end' => '2016-08-21'
    ],
    [
        'start' => '2016-08-22',
        'end' => '2016-08-28'
    ],
    [
        'start' => '2016-08-29',
        'end' => '2016-08-31'
    ]
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment