skip to Main Content

I’m creating a calendar with Sunday being the start of each week and I want to present the week number of the year before each row of dates.

This is my calendar

my calendar

How can I add week numbers like this:

This is what I need

My code:

<?php
function generate_calendar($month, $year) {
    $calendar = array();
    $days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
    $first_day_of_month = date('w', strtotime("$year-$month-01"));
    $week_number = 1;
    $week = array();
    
    // Determine the week number offset
    $days_from_january_1st = strtotime("$year-01-01");
    $days_to_first_day_of_month = strtotime("$year-$month-01");
    $week_number_offset = floor(($days_to_first_day_of_month - $days_from_january_1st) / 604800);
    
    // Check if the last week of the previous month is full (7 days)
    $last_week_of_previous_month = $week_number_offset;

    if ($month > 1) {
        $previous_month = $month - 1;
        $previous_month_year = $year;

    $previous_month_year = date("Y", strtotime("-1 month" , strtotime("$year-$month-01")));
    $previous_month = date("n", strtotime("-1 month" , strtotime("$year-$month-01")));

        if ($previous_month == 0) {
            $previous_month = 12;
            $previous_month_year = $year - 1;
        }

        $days_in_previous_month = cal_days_in_month(CAL_GREGORIAN, $previous_month, $previous_month_year);
        $last_day_of_previous_month = date('w', strtotime("$previous_month_year-$previous_month-$days_in_previous_month"));
        if ($last_day_of_previous_month == 6) {
            $last_week_of_previous_month=$last_week_of_previous_month + 1;
        } else {
            // Check if the last week of the previous month only has a few days
            $last_week_of_previous_month = $last_week_of_previous_month;
        }
    }
    
    // Generate the previous month's days
    for ($i = 1; $i <= $first_day_of_month; $i++) {
        array_unshift($week, "");
    }
    
    // Generate the current month's days
    for ($i = 1; $i <= $days_in_month; $i++) {
        $week[] = $i;
        if (count($week) == 7) {
            $calendar[$week_number + $last_week_of_previous_month] = $week;
            $week_number++;
            $week = array();
        }
    }
    
    // Generate the next month's days
    $remaining_days = 7 - count($week);
    for ($i = 1; $i <= $remaining_days; $i++) {
        $week[] = '';
    }
    
    if (!empty($week)) {
        $calendar[$week_number + $last_week_of_previous_month] = $week;
    }
    
    return $calendar;
}

$year = 2022;
echo "<table>n";
echo "  <tr>n";
echo "    <th colspan='3'>$year</th>n";
echo "  </tr>n";

echo "  <tr>n";
for($i=1; $i<=12; $i++){

$month_name = date('F Y', strtotime("$year-$i-01"));
$calendar = generate_calendar($i, $year);


echo "<td>n";
echo "<table>n";
echo "  <tr>n";
echo "    <th colspan='8'>$month_name</th>n";
echo "  </tr>n";
echo "  <tr>n";
echo "    <th>Week</th>n";
echo "    <th>Sun</th>n";
echo "    <th>Mon</th>n";
echo "    <th>Tue</th>n";
echo "    <th>Wed</th>n";
echo "    <th>Thu</th>n";
echo "    <th>Fri</th>n";
echo "    <th>Sat</th>n";
echo "  </tr>n";
foreach ($calendar as $week_number => $week) {
    echo "  <tr>n";
    echo "    <td>$week_number</td>n";
    foreach ($week as $day) {
        if (empty($day)) {
            echo "    <td></td>n";
        } else {
            echo "    <td>$day</td>n";
        }
    }
    echo "  </tr>n";
}
echo "</table>n";
echo "</td>n";

if($i==3 || $i==6 || $i==9){
echo "  </tr>n";
echo "  <tr>n";
}

}

echo "  </tr>n";
echo "</table>n";

?>

Trying to add week number which counts from first week of January (if last week of previous month is not full 7 days then first week of current month start from last week of previous month), but my code only count from first week of current month.

2

Answers


  1. I don’t believe there is any way to set the start day of the week in the standard library of PHP without manual calculation, but you can do it easily with the intl library (make sure the intl PHP extension is enabled):

    $cal = IntlGregorianCalendar::createInstance();
    
    // Set start of week to Sunday
    $cal->setFirstDayOfWeek(IntlGregorianCalendar::DOW_SUNDAY);
    
    // Get week number of the year for the current date
    $weekOfYear = intval(IntlDateFormatter::formatObject($cal, 'w'));
    
    // Advance to the next week
    $cal->add(IntlGregorianCalendar::FIELD_WEEK_OF_YEAR, 1);
    
    // ect...
    
    Login or Signup to reply.
  2. I managed to get the right result (as far as I tested) with IntlCalendar and its FIELD_WEEK_OF_YEAR constant instead of counting Sundays.

    I did some refactoring of your function, but ran out of time to do a full reduction of the script (there may still be lines that can be simplified/condensed).

    Code: (Demo)

    function generate_calendar(int $month, int $year) {
        $calendar = [];
        
        $week_number = (IntlCalendar::fromDateTime ("$year-$month-01"))->get(IntlCalendar::FIELD_WEEK_OF_YEAR);
        $month_start = new DateTime("$year-$month-01");
    
        // Generate the previous month's days
        if ($first_day = $month_start->format('w')) {
            $week = array_fill(1, $first_day, '');
        }
    
        // Generate the current month's days
        $days_in_month = $month_start->format('t');
        for ($i = 1; $i <= $days_in_month; $i++) {
            $week[] = $i;
            if (count($week) == 7) {
                $calendar[$week_number] = $week;
                $week_number++;
                $week = [];
            }
        }
    
        if ($week) {
            // Generate empty days for the next month
            $calendar[$week_number] = array_pad($week, 7, '');
        }
        
        return $calendar;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search