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

前端 未结 17 1864
星月不相逢
星月不相逢 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:17

    The rule is that the first week of a year is the week that contains the first Thursday of the year.

    I personally use Zend_Date for this kind of calculation and to get the week for today is this simple. They have a lot of other useful functions if you work with dates.

    $now = Zend_Date::now();
    $week = $now->get(Zend_Date::WEEK);
    // 10
    
    0 讨论(0)
  • 2020-11-27 15:19

    To get the week number for a date in North America I do like this:

    function week_number($n)
    {
        $w = date('w', $n);
        return 1 + date('z', $n + (6 - $w) * 24 * 3600) / 7;
    }
    
    $n = strtotime('2022-12-27');
    printf("%s: %d\n", date('D Y-m-d', $n), week_number($n));
    

    and get:

    Tue 2022-12-27: 53

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-11-27 15:21

    Becomes more difficult when you need year and week.
    Try to find out which week is 01.01.2017.
    (It is the 52nd week of 2016, which is from Mon 26.12.2016 - Sun 01.01.2017).

    After a longer search I found

    strftime('%G-%V',strtotime("2017-01-01"))
    

    Result: 2016-52


    https://www.php.net/manual/de/function.strftime.php
    ISO-8601:1988 week number of the given year, starting with the first week of the year with at least 4 weekdays, with Monday being the start of the week. (01 through 53)


    The equivalent in mysql is DATE_FORMAT(date, '%x-%v') https://www.w3schools.com/sql/func_mysql_date_format.asp
    Week where Monday is the first day of the week (01 to 53).


    Could not find a corresponding solution with date() or DateTime.
    At least not without solutions like "+1day, last monday".

    0 讨论(0)
  • 2020-11-27 15:22

    Use PHP's date function
    http://php.net/manual/en/function.date.php

    date("W", $yourdate)
    
    0 讨论(0)
  • 2020-11-27 15:23
    function last_monday($date) 
    {
        if (!is_numeric($date))
            $date = strtotime($date);
        if (date('w', $date) == 1)
            return $date;
        else
            return date('Y-m-d',strtotime('last monday',$date));
    }
    $date = '2021-01-04';  //Enter custom date
    $year = date('Y',strtotime($date));
    $date1 = new DateTime($date);
    $ldate = last_monday($year."-01-01");
    $date2 = new DateTime($ldate);
    $diff = $date2->diff($date1)->format("%a");
    $diff = $diff/7;
    $week = intval($diff) + 1;
    echo $week;
    //Returns 2.
    
    0 讨论(0)
提交回复
热议问题