Anu Anu - 2 months ago 6
PHP Question

Split the current month in to weeks in php

I want to split the current month in to weeks like first day to saturday and then sunday to next saturday.For ex: for May month, So i want to split that like

2016-05-01 to 2016-05-07
2016-05-08 to 2016-05-14
2016-05-15 to 2016-05-21
2016-05-22 to 2016-05-28
2016-05-29 to 2016-05-31


if i try the below code,i didnt get exact result.

<?php

$start_date = date('Y-m-d', strtotime('2016-06-01'));
$end_date = date('Y-m-d', strtotime('2016-06-30'));
$i=1;
for($date = $start_date; $date <= $end_date; $date = date('Y-m-d', strtotime($date. ' + 7 days'))) {
echo getWeekDates($date, $start_date, $end_date, $i);
echo "\n";
$i++;
}

function getWeekDates($date, $start_date, $end_date, $i) {
$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.'<br>';
}

?>


i got like

2016-05-01 - 2016-05-01
2016-05-01 - 2016-05-08
2016-05-08 - 2016-05-15
2016-05-15 - 2016-05-22
2016-05-22 - 2016-05-29


In for loop, while checking last set of days, conditon get failed .so it doesnt calculate 30,31.

How can i do that?

Answer

DateTime, DatePeriod and DateInterval are your friends to do that quickly!

See online.

<?php
/**
 * @file
 * Awnser to http://stackoverflow.com/q/37224961/392725
 *
 * @link http://stackoverflow.com/a/37228497/392725
 */
date_default_timezone_set('Europe/Paris');

function getWeekDates(DateTimeInterface $date, $format = 'Y-m-d') {
  $dt        = \DateTimeImmutable::createFromMutable($date);
  $first_day = $dt->modify('first day of this month');
  $last_day  = $dt->modify('last day of this month');
  $period    = new \DatePeriod(
    $first_day,
    \DateInterval::createFromDateString('sunday this week'),
    $last_day,
    \DatePeriod::EXCLUDE_START_DATE
  );

  $weeks = [$first_day->format($format)];
  foreach ($period as $d) {
    $weeks[] = $d->modify('-1 day')->format($format);
    $weeks[] = $d->format($format);
  }
  $weeks[] = $last_day->format($format);

  return array_chunk($weeks, 2);
}

echo "Weeks of the current month:\n";
$weeks = getWeekDates(new \DateTime('now'));
array_walk($weeks, function ($week) {
  vprintf("%s to %s\n", $week);
});

echo "\nWeeks of the month may 2016:\n";
$weeks = getWeekDates(new \DateTime('2016-05'));
array_walk($weeks, function ($week) {
  vprintf("%s to %s\n", $week);
});

echo "\nWeeks of the month june 2016:\n";
$weeks = getWeekDates(new \DateTime('2016-06'));
array_walk($weeks, function ($week) {
  vprintf("%s to %s\n", $week);
});

echo "\nWeeks of the month october 2016:\n";
$weeks = getWeekDates(new \DateTime('2016-10'));
array_walk($weeks, function ($week) {
  vprintf("%s to %s\n", $week);
});

Result:

Weeks of the current month:
2016-05-01 to 2016-05-07
2016-05-08 to 2016-05-14
2016-05-15 to 2016-05-21
2016-05-22 to 2016-05-28
2016-05-29 to 2016-05-31

Weeks of the month may 2016:
2016-05-01 to 2016-05-07
2016-05-08 to 2016-05-14
2016-05-15 to 2016-05-21
2016-05-22 to 2016-05-28
2016-05-29 to 2016-05-31

Weeks of the month june 2016:
2016-06-01 to 2016-06-04
2016-06-05 to 2016-06-11
2016-06-12 to 2016-06-18
2016-06-19 to 2016-06-25
2016-06-26 to 2016-06-30

Weeks of the month october 2016:
2016-10-01 to 2016-10-01
2016-10-02 to 2016-10-08
2016-10-09 to 2016-10-15
2016-10-16 to 2016-10-22
2016-10-23 to 2016-10-29
2016-10-30 to 2016-10-31
Comments