Search code examples
phparraysdatetimegroupingdate-formatting

Convert array of `YYYMMDD` date strings to a delimited string of days grouped by month


PHP Dates are wonderful things +1 year for example. However I'm getting myself in a bit of a mess. I have three dates spanning two months and I want to make an elegant string "28, 29 February & 1 March" from an array of 3 dates in the form YYYYMMDD. The exact number of dates is not known, minimum 1 probable max 4

Other than some rather tortuous str_replace manipulation, how do I get from the output of this to my desired format?

NB: no more than 2 months, maybe all in one month.

$dates_array = ['20240228', '20240229', '20240301'];

foreach ($dates_array as $date) :
  $datetimes[]  = new DateTime($date);
endforeach;

// print_r($datetimes);

foreach ($datetimes as $key=>$date) :
  $month = $date->format('F');
  $day = $date->format('j');                                    
  $date_array[]= $day." ".$month." & ";
endforeach;

$date_string =  join( ' ', $date_array ) ;

echo $date_string;

// 28 February & 29 February & 1 March & 

Solution

  • I managed to create this:

    $dates = ['20240228', '20240229', '20240301'];
    
    function formatDates(array $datesInput) {
        foreach ($datesInput as $datesKey => $date) {
            $date  = new DateTime($date);
            $month = $date->format('F');
            $day   = $date->format('j');
            if ($datesKey == 0) {
                $datesOutput = $day;
            } elseif ($currentMonth <> $month) {
                $datesOutput .= " $currentMonth & $day";
            } else {
                $datesOutput .= ", $day";
            }
            $currentMonth = $month;
        }
        return "$datesOutput $month";
    }
    
    echo formatDates($dates);
    

    This returns:

    28, 29 February & 1 March
    

    It is not all that complicated. I did however put everything in a function because I would otherwise have to create quite a few global variables, and that's seen as bad practice.

    For a demo see: https://3v4l.org/gUWih