42

hi how to find no of weeks and each mondays date between 2 dates. for ex 10-07-2009 to today .

Note :consider leap year and other date related constrains also.

ArK
  • 20,698
  • 67
  • 109
  • 136

10 Answers10

84

Here's an alternative solution using DateTime:-

function datediffInWeeks($date1, $date2)
{
    if($date1 > $date2) return datediffInWeeks($date2, $date1);
    $first = DateTime::createFromFormat('m/d/Y', $date1);
    $second = DateTime::createFromFormat('m/d/Y', $date2);
    return floor($first->diff($second)->days/7);
}

var_dump(datediffInWeeks('1/2/2013', '6/4/2013'));// 21

See it working

vascowhite
  • 18,120
  • 9
  • 61
  • 77
  • 2
    I think this answer is more complete than accepted, specially if @Piskvor is right when saying than datediff has bugs. – Hector Ordonez Feb 15 '14 at 13:15
  • 1
    the floor here --- floor($first->diff($second)->days/7) is causing issues for me ... so it could be a matter of whether your programs needs to look at 2.8 weeks as 3 weeks or 2 weeks. – Aukhan Apr 15 '15 at 13:00
  • 3
    @Aukhan Then feel free to modify it to suit :) There is no way a snippet of code posted here will suit every scenario, they are merely suggested starting points. Perhaps [`round()`](http://php.net/round) would suit you better? – vascowhite Apr 16 '15 at 04:15
  • @vascowhite ... yea :) i did modify it that day to suit my needs , I wanted to look at it through ceil(). thanks for the snippet ! I think should rather be a part of core php ... love the way how moment.js handles these things ;) – Aukhan Apr 22 '15 at 12:08
23
echo datediff('ww', '9 July 2003', '4 March 2004', false);

Find the function on the site below: http://www.addedbytes.com/code/php-datediff-function/

UPDATE

Link is now broken (Sept 2017), so function below pulled from webarchive:

<?php

/**
 * @param $interval
 * @param $datefrom
 * @param $dateto
 * @param bool $using_timestamps
 * @return false|float|int|string
 */
function datediff($interval, $datefrom, $dateto, $using_timestamps = false)
{
    /*
    $interval can be:
    yyyy - Number of full years
    q    - Number of full quarters
    m    - Number of full months
    y    - Difference between day numbers
           (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".)
    d    - Number of full days
    w    - Number of full weekdays
    ww   - Number of full weeks
    h    - Number of full hours
    n    - Number of full minutes
    s    - Number of full seconds (default)
    */

    if (!$using_timestamps) {
        $datefrom = strtotime($datefrom, 0);
        $dateto   = strtotime($dateto, 0);
    }

    $difference        = $dateto - $datefrom; // Difference in seconds
    $months_difference = 0;

    switch ($interval) {
        case 'yyyy': // Number of full years
            $years_difference = floor($difference / 31536000);
            if (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom), date("j", $datefrom), date("Y", $datefrom)+$years_difference) > $dateto) {
                $years_difference--;
            }

            if (mktime(date("H", $dateto), date("i", $dateto), date("s", $dateto), date("n", $dateto), date("j", $dateto), date("Y", $dateto)-($years_difference+1)) > $datefrom) {
                $years_difference++;
            }

            $datediff = $years_difference;
        break;

        case "q": // Number of full quarters
            $quarters_difference = floor($difference / 8035200);

            while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($quarters_difference*3), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
                $months_difference++;
            }

            $quarters_difference--;
            $datediff = $quarters_difference;
        break;

        case "m": // Number of full months
            $months_difference = floor($difference / 2678400);

            while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
                $months_difference++;
            }

            $months_difference--;

            $datediff = $months_difference;
        break;

        case 'y': // Difference between day numbers
            $datediff = date("z", $dateto) - date("z", $datefrom);
        break;

        case "d": // Number of full days
            $datediff = floor($difference / 86400);
        break;

        case "w": // Number of full weekdays
            $days_difference  = floor($difference / 86400);
            $weeks_difference = floor($days_difference / 7); // Complete weeks
            $first_day        = date("w", $datefrom);
            $days_remainder   = floor($days_difference % 7);
            $odd_days         = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder?

            if ($odd_days > 7) { // Sunday
                $days_remainder--;
            }

            if ($odd_days > 6) { // Saturday
                $days_remainder--;
            }

            $datediff = ($weeks_difference * 5) + $days_remainder;
        break;

        case "ww": // Number of full weeks
            $datediff = floor($difference / 604800);
        break;

        case "h": // Number of full hours
            $datediff = floor($difference / 3600);
        break;

        case "n": // Number of full minutes
            $datediff = floor($difference / 60);
        break;

        default: // Number of full seconds (default)
            $datediff = $difference;
        break;
    }

    return $datediff;
}
MrMarlow
  • 856
  • 4
  • 17
Tom Gullen
  • 61,249
  • 84
  • 283
  • 456
  • 3
    Would be nice, if not for a not-so-subtle bug in many ranges including 2012 (and 2016, and 2020, and 2024): Feb 29. – Piskvor left the building Jan 02 '12 at 16:01
  • 4
    It would be nice if you include the code of `datediff`, just in case the link gets invalid. – AbcAeffchen Apr 13 '15 at 00:29
  • 13
    How the hell am I googling for a function to find the difference in weeks between two dates, and ending up on StackOverflow ... reading a comment that links to my own website and the code I already wrote to solve this problem? I think I'm losing it ... – Dave Child Jan 06 '17 at 13:55
  • @Piskvor alleging something like that for such a complex function you should have some sort of reproducible code, it works great, I don't see any bugs with it – raveren Apr 02 '19 at 07:39
  • @DaveChild found this function that counts weeks in between 2 dates, have you seen it? – Harry Bosh Apr 14 '21 at 01:58
23
$diff = strtotime($dateto, 0) - strtotime($datefrom, 0);
echo floor($diff / 604800);
Community
  • 1
  • 1
silent
  • 3,843
  • 23
  • 29
3

This work great

function weeks_between($datefrom, $dateto)
    {
        $datefrom = DateTime::createFromFormat('d/m/Y H:i:s',$datefrom);
        $dateto = DateTime::createFromFormat('d/m/Y H:i:s',$dateto);
        $interval = $datefrom->diff($dateto);
        $week_total = $interval->format('%a')/7;
        return floor($week_total);

    }

weeks_between("25/02/2000 11:30:00","05/06/2015 11:29:59")
2

The following function computes the "spoken weeks" between two timestamps (i.e. monday is next week if you are on saturday).

function days_between($datefrom,$dateto){
    $fromday_start = mktime(0,0,0,date("m",$datefrom),date("d",$datefrom),date("Y",$datefrom));
    $diff = $dateto - $datefrom;
    $days = intval( $diff / 86400 ); // 86400  / day

    if( ($datefrom - $fromday_start) + ($diff % 86400) > 86400 )
        $days++;

    return  $days;
}

function weeks_between($datefrom, $dateto)
{
    $day_of_week = date("w", $datefrom);
    $fromweek_start = $datefrom - ($day_of_week * 86400) - ($datefrom % 86400);
    $diff_days = days_between($datefrom, $dateto);
    $diff_weeks = intval($diff_days / 7);
    $seconds_left = ($diff_days % 7) * 86400;

    if( ($datefrom - $fromweek_start) + $seconds_left > 604800 )
        $diff_weeks ++;

    return $diff_weeks;
}
Mat
  • 1,022
  • 2
  • 9
  • 24
1

I updated Tom's code from above to make the function auto-detect string or int date/time.

<?php
/**
 * @param $interval
 * @param $datefrom
 * @param $dateto
 * @param bool $using_timestamps // Removed 08-29-2019 Jay Simons - Now auto-detects
 * @return false|float|int|string
 */
function datediff($interval, $datefrom, $dateto)
{
    /*
    $interval can be:
    yyyy - Number of full years
    q    - Number of full quarters
    m    - Number of full months
    y    - Difference between day numbers
           (eg 1st Jan 2004 is "1", the first day. 2nd Feb 2003 is "33". The datediff is "-32".)
    d    - Number of full days
    w    - Number of full weekdays
    ww   - Number of full weeks
    h    - Number of full hours
    n    - Number of full minutes
    s    - Number of full seconds (default)
    */
/*Remove
    if (!$using_timestamps) {
        $datefrom = strtotime($datefrom, 0);
        $dateto   = strtotime($dateto, 0);
    }
*/
    // Auto-detect string date or int date:
    $dateto_str = strtotime($dateto);
    $datefrom_str = strtotime($datefrom);
    if ($dateto_str) $dateto = $dateto_str;
    if ($datefrom_str) $datefrom = $datefrom_str;

    $difference        = $dateto - $datefrom; // Difference in seconds
    $months_difference = 0;

    switch ($interval) {
        case 'yyyy': // Number of full years
            $years_difference = floor($difference / 31536000);
            if (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom), date("j", $datefrom), date("Y", $datefrom)+$years_difference) > $dateto) {
                $years_difference--;
            }

            if (mktime(date("H", $dateto), date("i", $dateto), date("s", $dateto), date("n", $dateto), date("j", $dateto), date("Y", $dateto)-($years_difference+1)) > $datefrom) {
                $years_difference++;
            }

            $datediff = $years_difference;
        break;

        case "q": // Number of full quarters
            $quarters_difference = floor($difference / 8035200);

            while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($quarters_difference*3), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
                $months_difference++;
            }

            $quarters_difference--;
            $datediff = $quarters_difference;
        break;

        case "m": // Number of full months
            $months_difference = floor($difference / 2678400);

            while (mktime(date("H", $datefrom), date("i", $datefrom), date("s", $datefrom), date("n", $datefrom)+($months_difference), date("j", $dateto), date("Y", $datefrom)) < $dateto) {
                $months_difference++;
            }

            $months_difference--;

            $datediff = $months_difference;
        break;

        case 'y': // Difference between day numbers
            $datediff = date("z", $dateto) - date("z", $datefrom);
        break;

        case "d": // Number of full days
            $datediff = floor($difference / 86400);
        break;

        case "w": // Number of full weekdays
            $days_difference  = floor($difference / 86400);
            $weeks_difference = floor($days_difference / 7); // Complete weeks
            $first_day        = date("w", $datefrom);
            $days_remainder   = floor($days_difference % 7);
            $odd_days         = $first_day + $days_remainder; // Do we have a Saturday or Sunday in the remainder?

            if ($odd_days > 7) { // Sunday
                $days_remainder--;
            }

            if ($odd_days > 6) { // Saturday
                $days_remainder--;
            }

            $datediff = ($weeks_difference * 5) + $days_remainder;
        break;

        case "ww": // Number of full weeks
            $datediff = floor($difference / 604800);
        break;

        case "h": // Number of full hours
            $datediff = floor($difference / 3600);
        break;

        case "n": // Number of full minutes
            $datediff = floor($difference / 60);
        break;

        default: // Number of full seconds (default)
            $datediff = $difference;
        break;
    }

    return $datediff;
}
?>
Jay
  • 353
  • 4
  • 8
0
    This will count a single day as one week and if you select sunday of one week and monday of another. though only 2 days are there but of different weeks therefore 2 weeks will be counted.


    Also works for different years


        function return_week($datee){
            $duedt = explode("-", $datee);
            $date  = mktime(0, 0, 0, $duedt[1], $duedt[2], $duedt[0]);
            $week  = (int)date('W', $date);
            return $week ;

        }

       function weeks_between($strtDate, $endDate){  
    // input dates of format yyyy-mm-dd between which you want to get number of weeks
    $start_date = DateTime::createFromFormat("Y-m-d", $strtDate);
    $end_date =  DateTime::createFromFormat("Y-m-d", $endDate);
    $start_year = $start_date->format("Y");
    $end_year = $end_date->format("Y");
    $start_month = $start_date->format("m");
    $end_month = $end_date->format("m");
    $week1  = return_week($strtDate);
    $week2  = return_week($endDate);
    $diff = $end_year - $start_year;;
    if($end_month<$start_month && $start_year!=$end_year ){
        $week_diff = (52*$diff-$week1)+$week2+1;
        return ($start_year==$end_year)?$week_diff:abs($week_diff);
    }else{
        $week_diff = $week2-$week1+1;
        return ($start_year==$end_year)?$week_diff:abs($week_diff)+52*$diff;
    }


    }

//call to function
weeks_between(""2018-10-21,"2019-10-21");
0
    $formt_start_date = new DateTime($start_date);
    $formt_end_date = new DateTime($end_date);
    for ($i = $formt_start_date; $i < $formt_end_date; $i->modify('+7 day')) {
        $week_frequency[] = new DateTime($i->format("Y-m-d"));

    }
  • 1
    While this code may solve the OP's issue, it is better to add context, or an explanation as to why this solves the OP's problem, so future visitors can learn from your post, and apply this knowledge to their own issues. High Quality Answers are much more likely to be upvoted, and contribute to the value and quality of SO as a platform. You can also add a link to documentation, if that helps. – SherylHohman May 07 '20 at 17:59
-1

To check Full Code Click here

All the week numbers between two dates in PHP

getNoOfWeek() will return array of week no. with year. You can change formatting of this array from week_text_alter().

function getNoOfWeek($startDate, $endDate){
  // convert date in valid format
  $startDate = date("Y-m-d", strtotime($startDate));
  $endDate = date("Y-m-d", strtotime($endDate));
  $yearEndDay = 31;
  $weekArr = array();
  $startYear = date("Y", strtotime($startDate));
  $endYear = date("Y", strtotime($endDate));

  if($startYear != $endYear) {
    $newStartDate = $startDate;

    for($i = $startYear; $i <= $endYear; $i++) {
      if($endYear == $i) {
        $newEndDate = $endDate;
      } else {
        $newEndDate = $i."-12-".$yearEndDay;
      }
      $startWeek = date("W", strtotime($newStartDate));
      $endWeek = date("W", strtotime($newEndDate));
      if($endWeek == 1){
        $endWeek = date("W", strtotime($i."-12-".($yearEndDay-7)));
      }
      $tempWeekArr = range($startWeek, $endWeek);
      array_walk($tempWeekArr, "week_text_alter", 
         array('pre' => 'Week ', 'post' => " '". substr($i, 2, 2) ));
      $weekArr = array_merge($weekArr, $tempWeekArr);

      $newStartDate = date("Y-m-d", strtotime($newEndDate . "+1 days"));
    }
  } else {
    $startWeek = date("W", strtotime($startDate));
    $endWeek = date("W", strtotime($endDate));
    $endWeekMonth = date("m", strtotime($endDate));
    if($endWeek == 1 && $endWeekMonth == 12){
      $endWeek = date("W", strtotime($endYear."-12-".($yearEndDay-7)));
    }
    $weekArr = range($startWeek, $endWeek);
    array_walk($weekArr, "week_text_alter", 
       array('pre' => 'Week ', 'post' => " '". substr($startYear, 2, 2)));
  }
  $weekArr = array_fill_keys($weekArr, 0);
  return $weekArr;
}

function week_text_alter(&$item1, $key, $prefix)
{
  $item1 = $prefix['pre']. $item1 . $prefix['post'];
}


Output 1 -
$weekArr = getNoOfWeek('2014-01-01', '2014-02-10');

Array
(
    [Week 1 '14] => 0
    [Week 2 '14] => 0
    [Week 3 '14] => 0
    [Week 4 '14] => 0
    [Week 5 '14] => 0
    [Week 6 '14] => 0
    [Week 7 '14] => 0
)

Output 2 -
$weekArr = getNoOfWeek('2013-12-01', '2014-02-10');

Array
(
    [Week 48 '13] => 0
    [Week 49 '13] => 0
    [Week 50 '13] => 0
    [Week 51 '13] => 0
    [Week 52 '13] => 0
    [Week 1 '14] => 0
    [Week 2 '14] => 0
    [Week 3 '14] => 0
    [Week 4 '14] => 0
    [Week 5 '14] => 0
    [Week 6 '14] => 0
    [Week 7 '14] => 0
)

Hope this will help you.

Gaurav Porwal
  • 503
  • 3
  • 6
-1

PHP number of week between 2 dates issue

Below is the solution (corrected solution for one question asked in the post - https://stackoverflow.com/questions/27560850/php-number-of-week-between-2-dates-issue) to find out the no of weeks between the date range.

As the below solution uses the date difference , for inclusion of the start date week one will have to use the floor function and for the inclusion of the end date week ceil has to be used then only it returns the correct number of weeks

$strtDate = '2014-01-01';
$endDate = '2015-03-17';

$startDateWeekCnt = round(floor( date('d',strtotime($strtDate)) / 7)) ;
// echo $startDateWeekCnt ."\n";
$endDateWeekCnt = round(ceil( date('d',strtotime($endDate)) / 7)) ;
//echo $endDateWeekCnt. "\n";

$datediff = strtotime(date('Y-m',strtotime($endDate))."-01") - strtotime(date('Y-m',strtotime($strtDate))."-01");
$totalnoOfWeek = round(floor($datediff/(60*60*24)) / 7) + $endDateWeekCnt - $startDateWeekCnt ;
echo $totalnoOfWeek ."\n";
Community
  • 1
  • 1