简体   繁体   中英

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

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.

<?php
$ddate = "2012-10-18";
$duedt = explode("-",$ddate);
$date = mktime(0, 0, 0, $duedt[2], $duedt[1],$duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: ".$week;
?>

Is it wrong and a coincidence that the digits are reversed? Or am I nearly there?

Today, using PHP's DateTime objects is better:

<?php
$ddate = "2012-10-18";
$date = new DateTime($ddate);
$week = $date->format("W");
echo "Weeknummer: $week";

It's because in mktime() , it goes like this:

mktime(hour, minute, second, month, day, year);

Hence, your order is wrong.

<?php
$ddate = "2012-10-18";
$duedt = explode("-", $ddate);
$date  = mktime(0, 0, 0, $duedt[1], $duedt[2], $duedt[0]);
$week  = (int)date('W', $date);
echo "Weeknummer: " . $week;
?>
$date_string = "2012-10-18";
echo "Weeknummer: " . date("W", strtotime($date_string));

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

date("W", $yourdate)

This get today date then tell the week number for the week

<?php
 $date=date("W");
 echo $date." Week Number";
 ?>

Just as a suggestion:

<?php echo date("W", strtotime("2012-10-18")); ?>

Might be a little simpler than all that lot.

Other things you could do:

<?php echo date("Weeknumber: W", strtotime("2012-10-18 01:00:00")); ?>
<?php echo date("Weeknumber: W", strtotime($MY_DATE)); ?>

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.

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

The most of the above given examples create a problem when a year has 53 weeks (like 2020). So every fourth year you will experience a week difference. This code does not:

$thisYear = "2020";
$thisDate = "2020-04-24"; //or any other custom date
$weeknr = date("W", strtotime($thisDate)); //when you want the weeknumber of a specific week, or just enter the weeknumber yourself

$tempDatum = new DateTime();
$tempDatum->setISODate($thisYear, $weeknr);
$tempDatum_start = $tempDatum->format('Y-m-d');
$tempDatum->setISODate($thisYear, $weeknr, 7);
$tempDatum_end = $tempDatum->format('Y-m-d');

echo $tempDatum_start //will output the date of monday
echo $tempDatum_end // will output the date of sunday

How about using the IntlGregorianCalendar class?

Requirements : Before you start to use IntlGregorianCalendar make sure that libicu or pecl/intl is installed on the Server. So run on the CLI:

php -m

If you see intl in the [PHP Modules] list, then you can use IntlGregorianCalendar .

DateTime vs IntlGregorianCalendar : IntlGregorianCalendar is not better then DateTime . But the good thing about IntlGregorianCalendar is that it will give you the week number as an int .

Example:

$dateTime = new DateTime('21-09-2020 09:00:00');
echo $dateTime->format("W"); // string '39'

$intlCalendar = IntlCalendar::fromDateTime ('21-09-2020 09:00:00');
echo $intlCalendar->get(IntlCalendar::FIELD_WEEK_OF_YEAR); // integer 39
<?php
$ddate = "2012-10-18";
$duedt = explode("-",$ddate);
$date = mktime(0, 0, 0, $duedt[1], $duedt[2],$duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: ".$week;
?>

You had the params to mktime wrong - needs to be Month/Day/Year, not Day/Month/Year

To get Correct Week Count for Date 2018-12-31 Please use below Code

$day_count = date('N',strtotime('2018-12-31'));
$week_count = date('W',strtotime('2018-12-31'));    


if($week_count=='01' && date('m',strtotime('2018-12-31'))==12){
    $yr_count = date('y',strtotime('2018-12-31')) + 1;
}else{
    $yr_count = date('y',strtotime('2018-12-31'));
}

for get week number in jalai calendar you can use this:

$weeknumber = date("W"); //number week in year
$dayweek = date("w"); //number day in week
if ($dayweek == "6")
{
    $weeknumberint = (int)$weeknumber;
    $date2int++; 
    $weeknumber = (string)$date2int;
}

echo $date2;

result:

15

week number change in saturday

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".

Very simple Just one line:

<?php $date=date("W"); echo "Week " . $date; ?>"

You can also, for example like I needed for a graph, subtract to get the previous week like:

<?php $date=date("W"); echo "Week " . ($date - 1); ?>

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

Your code will work but you need to flip the 4th and the 5th argument.

I would do it this way

$date_string = "2012-10-18";
$date_int = strtotime($date_string);
$date_date = date($date_int);
$week_number = date('W', $date_date);
echo "Weeknumber: {$week_number}.";

Also, your variable names will be confusing to you after a week of not looking at that code, you should consider reading http://net.tutsplus.com/tutorials/php/why-youre-a-bad-php-programmer/

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.

试试这个解决方案

date( 'W', strtotime( "2017-01-01 + 1 day" ) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM