Get week number (in the year) from a date PHP

前端 未结 17 2030
星月不相逢
星月不相逢 2020-11-27 14:54

I want to take a date and work out its week number.

So far, I have the following. It is returning 24 when it should be 42.



        
17条回答
  •  栀梦
    栀梦 (楼主)
    2020-11-27 15:20

    I have tried to solve this question for years now, I thought I found a shorter solution but had to come back again to the long story. This function gives back the right ISO week notation:

    /**
     * calcweek("2018-12-31") => 1901
     * This function calculates the production weeknumber according to the start on 
     * monday and with at least 4 days in the new year. Given that the $date has
     * the following format Y-m-d then the outcome is and integer.
     *
     * @author M.S.B. Bachus
     *
     * @param date-notation PHP "Y-m-d" showing the data as yyyy-mm-dd
     * @return integer
     **/
    function calcweek($date) {
      // 1. Convert input to $year, $month, $day
      $dateset      = strtotime($date);
      $year         = date("Y", $dateset);
      $month        = date("m", $dateset);
      $day          = date("d", $dateset);
    
      $referenceday = getdate(mktime(0,0,0, $month, $day, $year));
      $jan1day      = getdate(mktime(0,0,0,1,1,$referenceday[year]));
    
      // 2. check if $year is a  leapyear
      if ( ($year%4==0 && $year%100!=0) || $year%400==0) {
        $leapyear = true;
      } else {
        $leapyear = false;
      }
    
      // 3. check if $year-1 is a  leapyear
      if ( (($year-1)%4==0 && ($year-1)%100!=0) || ($year-1)%400==0 ) {
        $leapyearprev = true;
      } else {
        $leapyearprev = false;
      }
    
      // 4. find the dayofyearnumber for y m d
      $mnth = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
      $dayofyearnumber = $day + $mnth[$month-1];
      if ( $leapyear && $month > 2 ) { $dayofyearnumber++; }
    
      // 5. find the jan1weekday for y (monday=1, sunday=7)
      $yy = ($year-1)%100;
      $c  = ($year-1) - $yy;
      $g  = $yy + intval($yy/4);
      $jan1weekday = 1+((((intval($c/100)%4)*5)+$g)%7);
    
      // 6. find the weekday for y m d
      $h = $dayofyearnumber + ($jan1weekday-1);
      $weekday = 1+(($h-1)%7);
    
      // 7. find if y m d falls in yearnumber y-1, weeknumber 52 or 53
      $foundweeknum = false;
      if ( $dayofyearnumber <= (8-$jan1weekday) && $jan1weekday > 4 ) {
        $yearnumber = $year - 1;
        if ( $jan1weekday = 5 || ( $jan1weekday = 6 && $leapyearprev )) {
          $weeknumber = 53;
        } else {
          $weeknumber = 52;
        }
        $foundweeknum = true;
      } else {
        $yearnumber = $year;
      }
    
      // 8. find if y m d falls in yearnumber y+1, weeknumber 1
      if ( $yearnumber == $year && !$foundweeknum) {
        if ( $leapyear ) {
          $i = 366;
        } else {
          $i = 365;
        }
        if ( ($i - $dayofyearnumber) < (4 - $weekday) ) {
          $yearnumber = $year + 1;
          $weeknumber = 1;
          $foundweeknum = true;
        }
      }
    
      // 9. find if y m d falls in yearnumber y, weeknumber 1 through 53
      if ( $yearnumber == $year && !$foundweeknum ) {
        $j = $dayofyearnumber + (7 - $weekday) + ($jan1weekday - 1);
        $weeknumber = intval( $j/7 );
        if ( $jan1weekday > 4 ) { $weeknumber--; }
      }
    
      // 10. output iso week number (YYWW)
      return ($yearnumber-2000)*100+$weeknumber;
    }
    

    I found out that my short solution missed the 2018-12-31 as it gave back 1801 instead of 1901. So I had to put in this long version which is correct.

提交回复
热议问题