There are two issues:
- The weeks number changes on different days (Monday for PHP, Sunday for MySQL)
- The first week of the year is determined differently (week containing the 4th of january for PHP, week starting with the first Sunday of the year for MySQL)
Which then causes these differences:
First day of year: | Mo | Tu | We | Th | Fr | Sa | Su |
PHP week | ------- 01 ------ | --- 52/53 -- |
MySQL week | ----------- 52/53 ----------| 01 |
We have 2 different cases, based on when the year starts:
- If it starts a Friday, Saturday or Sunday, PHP start week 1 "late" by 1 day (it can be solved by taking tomorrow's week number in PHP)
- It it starts a Monday, Tuesday, Wednesday or Thursday, you'll end up with an offset of 3-6 days, PHP being ahead this time, and it becomes a mess to solve.
So all in all, it seems you're better off just counting how many Sundays already passed this year, which apparently can be done with the following (adapted from this):
ceil((date("z") + 1 - date("w")) / 7); //added +1 in case the year starts a Sunday
And if it's 0 you count how many Sundays there were last year:
$ldly = strtotime(date("Y")-1)."-12-31"); //last day last year
ceil((date("z", $ldly ) + 1 - date("w", $ldly )) / 7);
By combining the two (and adding a parameter if you want to check dates other than today) you'd get:
function weekNum($date = false) {
$day = $date ? strtotime($date) : time();
if($res = ceil((date("z", $day) + 1 - date("w", $day)) / 7)){
return $res;
}
$ldly = strtotime((date("Y", $day)-1)."-12-31"); //last day last year
return ceil((date("z", $ldly ) + 1 - date("w", $ldly )) / 7);
}
I think this should always match with the MySQL date, but do your own tests to make sure! :)