Search code examples
phpdateprocedural-programming

How to adjust week and year for a menu ordering system in PHP


I'm updating a site for a restaurant where you can order daily menus and the menu changes weekly. The system only stores menus by the week, without the year specified. It had a bug that now (53rd week of 2015) if the admin wanted to enter the 1st week menu, it interpreted as 1st week of 2015. I want to change this to let them enter +-10 weeks into the next year and view back to the old year in january. So far my code looks like this, but i'm sure it won't give the right year after like march:

$year = date("Y");
$current_week = date("W");
$w_diff = abs($current_week - $week_number);

// If there is a year change (lower or higher current week and edit week) and it is within 10 weeks, we edit the other year, otherwise current year
// This code is imperfect, need to check mid year as it does not work
if ($current_week > $week_number && $w_diff >= 10) {$year++;}
elseif ($current_week < $week_number && $w_diff >= 10) {$year--;}

$week_number is the number of week the admin wants to edit the menu of. What I want is: If admin wants to edit the 9th week now, it shoud edit 2016, but if wants to see the 40th week, it should show 2015. In 1st week of 2016, for week 52 it should show 2015, but for week 10 it should show 2015. What can I change on that code to achieve this?


Solution

  • You could do something like this, making use of the modulo operator (%):

    function get_year($current_year, $current_week, $week_number, $max_forward) {
        $forward = (53 + $week_number - $current_week) % 53 <= $max_forward;
        if ($forward == $week_number < $current_week) {
            $year += $forward ? 1 : -1;
        }
        return $year;
    }
    

    The fourth argument sets the rule for when a week is considered future. So you would pass 10 to indicate you can look 10 weeks ahead, but any further would in fact be interpreted as looking back.

    To test the above function, you could do something like this:

    // test
    echo "curr \tweek \tyear<br>";  
    for ($current_week = 1; $current_week < 52; $current_week += 10) {
        for ($week_number = 1; $week_number < 52; $week_number += 10) {
            $year = get_year(2015, $current_week, $week_number, 10);
            echo "$current_week \t$week_number \t$year<br>";    
        }
    }
    

    Output is:

    curr    week    year
    1       1       2015
    1       11      2015
    1       21      2014
    1       31      2014
    1       41      2014
    1       51      2014
    11      1       2015
    11      11      2015
    11      21      2015
    11      31      2014
    11      41      2014
    11      51      2014
    21      1       2015
    21      11      2015
    21      21      2015
    21      31      2015
    21      41      2014
    21      51      2014
    31      1       2015
    31      11      2015
    31      21      2015
    31      31      2015
    31      41      2015
    31      51      2014
    41      1       2015
    41      11      2015
    41      21      2015
    41      31      2015
    41      41      2015
    41      51      2015
    51      1       2016
    51      11      2015
    51      21      2015
    51      31      2015
    51      41      2015
    51      51      2015