Skip to content
Advertisement

Split weeks of month

I’m trying to get a week range for the month, I’ve somewhat accomplished what I’m looking for but I’d like the code to be more reliable. The data ranges are going to be used to some MySQL queries where I can filter out data by data range.

What I’d like to achieve is to get something like the Windows 10 calendar. So the result is

2020-03-01 to 2020-03-01
2020-03-02 to 2020-03-08
2020-03-09 to 2020-03-15
2020-03-16 to 2020-03-22
2020-03-23 to 2020-03-29
2020-03-30 to 2020-03-31

Windows 10 calendar example

CODE

$start_date = date("Y-m-d", strtotime("first day of this month"));
$end_date = date("Y-m-d", strtotime("last day of this month"));

function getWeekDates($date, $start_date, $end_date) {
  $week =  date('W', strtotime($date));
  $year =  date('Y', strtotime($date));
  $from = date("Y-m-d", strtotime("{$year}-W{$week}+1"));
  if($from <= $start_date){
    $from = $start_date;
  }

  $to = date("Y-m-d", strtotime("{$year}-W{$week}-7"));
  if($to >= $end_date){
    $to = $end_date;
  }

  echo $from." to ".$to.'<br>';
}

for($date = $start_date; $date <= $end_date; $date = date('Y-m-d', strtotime($date. ' + 7 day'))){
  echo getWeekDates($date, $start_date, $end_date);
  echo "n";
}

Which results in

It’s missing the last two days of the month (30 and 31).

2020-03-01 to 2020-03-01
2020-03-02 to 2020-03-08
2020-03-09 to 2020-03-15
2020-03-16 to 2020-03-22
2020-03-23 to 2020-03-29

Advertisement

Answer

You can use DateTime objects to do this more readily, setting a start time as the first Monday on or before the start of the month, and then adding a week at a time until it is past the end of the month:

$month_start = new DateTime("first day of this month");
$month_end = new DateTime("last day of this month");

// find the Monday on/before the start of the month
$start_date = clone $month_start;
$start_date->modify((1 - $start_date->format('N')) . ' days');

while ($start_date <= $month_end) {
    echo max($month_start, $start_date)->format('Y-m-d') . ' to ' . min($start_date->modify('+6 days'), $month_end)->format('Y-m-d') . "n";
    $start_date->modify('+1 day');
}

Output:

2020-03-01 to 2020-03-01
2020-03-02 to 2020-03-08
2020-03-09 to 2020-03-15
2020-03-16 to 2020-03-22
2020-03-23 to 2020-03-29
2020-03-30 to 2020-03-31

Demo on 3v4l.org

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement