Search code examples
phparraysdateweek-number

Get week number in month from date in PHP?


I have an array of random dates (not coming from MySQL). I need to group them by the week as Week1, Week2, and so on upto Week5.

What I have is this:

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

What I need is a function to get the week number of the month by providing the date.

I know that I can get the weeknumber by doing date('W',strtotime('2015-09-01')); but this week number is the number between year (1-52) but I need the week number of the month only, e.g. in Sep 2015 there are 5 weeks:

  • Week1 = 1st to 5th
  • Week2 = 6th to 12th
  • Week3 = 13th to 19th
  • Week4 = 20th to 26th
  • Week5 = 27th to 30th

I should be able to get the week Week1 by just providing the date e.g.

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

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