5

According to formula https://en.wikipedia.org/wiki/ISO_week_date in the Weeks per year section you should be able to find each year with 53 weeks. I have copied the formula into PHP but it seems to mess up around 2020 returning 52 weeks instead of 53.

function weeks($year){
    $w = 52;
    $p = ($year+($year/4)-($year/100)+($year/400))%7;
    if ($p == 4 || ($p-1) == 3){
        $w++;
    }
    return $w." ".$p;
}

for ($i = 2000; $i <= 2144; $i++) {
    echo $i." (".weeks($i).") | ";
}

From Wikipedia

The following 71 years in a 400-year cycle have 53 weeks (371 days); years not listed have 52 weeks (364 days); add 2000 for current years:

004, 009, 015, 020, 026, 032, 037, 043, 048, 054, 060, 065, 071, 076, 082, 088, 093, 099, 105, 111, 116, 122, 128, 133, 139, 144

I know I can grab the total amount of weeks for a given year using the date() function but I'm just wondering if anyone knows the math since the formula on wikipedia seems to be wrong.

EDIT WORKING CODE

function p($year){
    return ($year+floor($year/4)-floor($year/100)+floor($year/400))%7;
}

function weeks($year){
    $w = 52;
    if (p($year) == 4 || p($year-1) == 3){
        $w++;
    }
    return $w; // returns the number of weeks in that year
}

for ($i = 2000; $i <= 2144; $i++) {
    echo $i." (".weeks($i).") | ";
}
Mike Lewis
  • 140
  • 1
  • 9

3 Answers3

2

Two problems that I can see:

  1. You missed the floor notation in the formula for p. In PHP that should be + int($year / 4) - int($year / 100) etc. not + ($year / 4) - ($year / 100) etc.

  2. p is a function, and the overall formula uses p(year) and p(year - 1). Your $p is equal to p(year), but $p - 1 is not equal to p(year - 1) (note that your second condition, ($p - 1) == 3 is just the same as your first condition, $p == 4 — this should make it clear that that's not what was intended). The easiest fix is to write it as a function in PHP also.

hobbs
  • 223,387
  • 19
  • 210
  • 288
  • Thank you I thought the floor notation was a square bracket and I tried to make the p function without using a function so I kinda messed myself up there. – Mike Lewis Jul 14 '17 at 19:11
0

You can use strftime to get the week number of the last day of the year.

for ($yr = 2000; $yr < 2144; ++$yr) {
    $weeks = (int) strftime("%U", strtotime("$yr-12-31 11:59"));
    if ($weeks === 53) {
        print("$yr has 53 weeks in it\n");
    }
}
amphetamachine
  • 27,620
  • 12
  • 60
  • 72
0

Not sure what the application needs in terms of "half or quarter weeks" but this little script will help you see the way the ISO week numbers work. The first ISO week of the year starts on Monday. The output is not exactly intuitive. https://iconoun.com/demo/temp_mikelewis.php

<?php // demo/temp_mikelewis.php
/**
 * Dealing with ISO Week Numbers
 *
 * https://stackoverflow.com/questions/45109650/how-to-calculate-if-a-year-has-53-weeks
 */
error_reporting(E_ALL);
echo '<pre>';

for ($i = 2000; $i <= 2035; $i++)
{
    echo PHP_EOL . "YEAR $i: " . date('D W', strtotime("$i-12-31"));
}
Ray Paseur
  • 2,106
  • 2
  • 13
  • 18