phpdateweek-number

How to get the week number in a month from a date, based on the day of the week


I have an array of random dates, e.g.:

$dates = array('2015-09-01','2015-09-05','2015-09-06','2015-09-15','2015-09-17');

I need to group them by the week as Week 1, Week 2, and so on up to Week 5. However, I need them based on the day of the week of the month. For example, take September 2015:

Screenshot of a calendar widget showing the month of September 2015, with day 1 of the month starting on a Tuesday

So:

What I need is a function to get the week number of the month based on the format above, just by providing the date.

I know that I can get the week number by doing date('W',strtotime('2015-09-01')); but this week number is the number within the entire year (1-52); I need the week number of the month only.

I should be able to get Week 1 by just providing the date, e.g.:

$weekNumber = getWeekNumber('2015-09-01') //output 1;
$weekNumber = getWeekNumber('2015-09-17') //output 3;
$weekNumber = getWeekNumber('2015-09-20') //output 4;

Solution

  • I think this relationship should be true and come in handy:

    Week of the month = Week of the year - Week of the year of first day of month + 1
    

    We also need to make sure that "overlapping" weeks from the previous year are handeled correctly - if January 1st is in week 52 or 53, it should be counted as week 0. In a similar fashion, if a day in December is in the first week of the next year, it should be counted as 53. (Previous versions of this answer failed to do this properly.)

    <?php
    
    function weekOfMonth($date) {
        //Get the first day of the month.
        $firstOfMonth = strtotime(date("Y-m-01", $date));
        //Apply above formula.
        return weekOfYear($date) - weekOfYear($firstOfMonth) + 1;
    }
    
    function weekOfYear($date) {
        $weekOfYear = intval(date("W", $date));
        if (date('n', $date) == "1" && $weekOfYear > 51) {
            // It's the last week of the previos year.
            return 0;
        }
        else if (date('n', $date) == "12" && $weekOfYear == 1) {
            // It's the first week of the next year.
            return 53;
        }
        else {
            // It's a "normal" week.
            return $weekOfYear;
        }
    }
    
    // A few test cases.
    echo weekOfMonth(strtotime("2020-04-12")) . " "; // 2
    echo weekOfMonth(strtotime("2020-12-31")) . " "; // 5
    echo weekOfMonth(strtotime("2020-01-02")) . " "; // 1
    echo weekOfMonth(strtotime("2021-01-28")) . " "; // 5
    echo weekOfMonth(strtotime("2018-12-31")) . " "; // 6
    

    To get weeks that starts with sunday, simply replace date("W", ...) with strftime("%U", ...).