3v4l.org

run code in 300+ PHP versions simultaneously
<?php $toParse = [ [new DateTime('2021-10-3')], [new DateTime('2022-01-25'),new DateTime('2022-01-26'),new DateTime('2022-01-27')], [new DateTime('2021-09-19'),new DateTime('2021-09-22')], [new DateTime('2022-02-28'),new DateTime('2022-03-01'),new DateTime('2022-03-02')], [new DateTime('2022-04-02'),new DateTime('2022-04-03'),new DateTime('2022-04-04'),new DateTime('2022-06-10'),new DateTime('2022-06-11'),new DateTime('2022-06-12'),new DateTime('2022-06-13')], [new DateTime('2021-12-01'),new DateTime('2021-12-02'),new DateTime('2021-12-03'),new DateTime('2021-12-08')] ]; function produceDateString(array $dates): string { // sort the dates sort($dates); // create an array of arrays that contain ranges of consecutive days $ranges = []; $currentRange = []; foreach ($dates as $date) { if(empty($currentRange) || consecutive(end($currentRange), $date)) { $currentRange[] = $date; } else { $ranges[] = $currentRange; $currentRange = [$date]; } } $ranges[] = $currentRange; // create the output string $output = ''; $previous = null; foreach ($ranges as $range) { // add a comma between each range if (!empty($output)) { $output .= ', '; } // the long format should be used on the first occurrence of the loop // or when the month of first date in the range doesn't match // the month of the last date in the previous range $format = $previous === null || end($previous)->format('m') !== reset($range)->format('m') ? 'M. j' : 'j'; // the output differes when there are 1 or multiple dates in a range if (count($range) > 1) { // the output differs when the end and start are in the sane month $output .= sameMonth(reset($range), end($range)) ? reset($range)->format($format).'-'.end($range)->format('j') : reset($range)->format('M. j').'-'.end($range)->format('M. j'); } else { $output .= reset($range)->format($format); } $previous = $range; } return $output; } function consecutive(DateTime $t1, DateTime $t2): bool { $t1->setTime(0, 0, 0, 0); $t2->setTime(0, 0, 0, 0); return(abs($t2->getTimestamp() - $t1->getTimestamp()) < 87000); } function sameMonth(DateTime $t1, DateTime $t2): bool { return $t1->format('Y-m') === $t2->format('Y-m'); } foreach ($toParse as $dates) { echo produceDateString($dates)."\r\n"; }

preferences:
31.3 ms | 407 KiB | 5 Q