Как показать все даты года по неделям

Вопрос или проблема

Я хочу отобразить все даты года, сгруппированные по неделям, и показать каждый день недели в одной строке таблицы. Код ниже показывает все даты года: (https://stackoverflow.com/a/4044939)

$now = mktime(0,0,0,1,1,2024);
$aYearLater = $now + 31536000;
$allDates = Array();

$friday = strtotime('Next Friday', strtotime('-1 Day', $now));
$saturday = strtotime('Next Saturday', strtotime('-1 Day', $now));
$sunday = strtotime('Next Sunday', strtotime('-1 Day', $now));
$monday = strtotime('Next Monday', strtotime('-1 Day', $now));
$tuesday = strtotime('Next Tuesday', strtotime('-1 Day', $now));
$wednesday = strtotime('Next Wednesday', strtotime('-1 Day', $now));
$thursday = strtotime('Next Thursday', strtotime('-1 Day', $now));

while(1){
    if($saturday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $saturday));
    $b = array('daynum'=>date('w', $saturday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($sunday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $sunday));
    $b = array('daynum'=>date('w', $sunday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($monday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $monday));
    $b = array('daynum'=>date('w', $monday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($tuesday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $tuesday));
    $b = array('daynum'=>date('w', $tuesday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($wednesday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $wednesday));
    $b = array('daynum'=>date('w', $wednesday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($thursday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $thursday));
    $b = array('daynum'=>date('w', $thursday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    if($friday > $aYearLater)
        break 1;
    $a = array('date'=>date('Y-m-d l', $friday));
    $b = array('daynum'=>date('w', $friday,'','','en'));
    $allDates[] = array_merge($a,$b); 
    $friday = strtotime('+1 Week', $friday);
    $saturday = strtotime('+1 Week', $saturday);
    $sunday = strtotime('+1 Week', $sunday);
    $monday = strtotime('+1 Week', $monday);
    $tuesday = strtotime('+1 Week', $tuesday);
    $wednesday = strtotime('+1 Week', $wednesday);
    $thursday = strtotime('+1 Week', $thursday);
}

foreach ($allDates as $k=>$v){
    echo $allDates[$k]['date'].'</br>'.$allDates[$k]['daynum'].'</br>';
}

как мне сгруппировать эти даты по неделям? Я не хочу использовать DateTime в PHP. спасибо.

Я искал на stackoverflow, но не смог найти ответ

Вы можете упростить код, увеличив $now на один день. Вы можете получить номер недели с помощью date('W'), но знайте, что если вы хотите, чтобы неделя начиналась с воскресенья, вам нужно немного манипулировать. Вот код, который будет увеличивать каждую дату и разделять дни на недели:

$now = mktime(0,0,0,1,1,2024);
$aYearLater = $now + 31536000;
$allDates = Array();

while($now <= $aYearLater) {
    $date = date('Y-m-d l', $now); // Форматированная дата
    $daynum = date('w', $now); // Номер дня
    $weekNum = $daynum == 0 ?  date('o-W', strtotime("+1 day",$now)) : date('o-W', $now); // Если номер дня равен 0, то увеличьте его на день, чтобы воскресенье переместилось в "следующий" номер недели
    $allDates[$weekNum][] = ['date' => $date, 'daynum' => $daynum];
    $now = strtotime('+1 day', $now);
}

foreach ($allDates as $week=>$days){ // Ключ - это год-номер недели, дни - подмассив
    foreach ($days as $k =>$v ) { // Проходим по каждому дню
        echo $v['date'].'</br>'.$v['daynum'].'</br>';
    }
}

Ваш массив будет выглядеть следующим образом

[
    "2024-01" => [
      0 => [
        "date" => "2024-01-01 Понедельник",
        "daynum" => "1",
      ],
      1 => [
        "date" => "2024-01-02 Вторник",
        "daynum" => "2",
      ],
      2 => [
        "date" => "2024-01-03 Среда",
        "daynum" => "3",
      ],
      3 => [
        "date" => "2024-01-04 Четверг",
        "daynum" => "4",
      ],
      4 => [
        "date" => "2024-01-05 Пятница",
        "daynum" => "5",
      ],
      5 => [
        "date" => "2024-01-06 Суббота",
        "daynum" => "6",
      ],
    ],
    "2024-02" => [
      0 => [
        "date" => "2024-01-07 Воскресенье",
        "daynum" => "0",
      ],
      1 => [
        "date" => "2024-01-08 Понедельник",
        "daynum" => "1",
      ],
....
    ]
]

Вот как бы я это сделал:

<?php

// Установить стартовые и конечные даты года
$year = date('Y');
$startDate = new DateTime("$year-01-01");
$endDate = new DateTime("$year-12-31");

// Создать интервал в один день
$interval = new DateInterval('P1D');

// Создать период от стартовой до конечной даты
$period = new DatePeriod($startDate, $interval, $endDate->add($interval));

// Инициализировать массив для хранения недель
$weeks = [];

// Пройти через каждую дату в периоде
foreach ($period as $date) {
    $weekNumber = $date->format('W'); // Получить номер недели
    $dayOfWeek = $date->format('N'); // Получить день недели (1 = понедельник, 7 = воскресенье)
    $weeks[$weekNumber][$dayOfWeek] = $date->format('Y-m-d');
}

// Отобразить даты в HTML-таблице
echo '<table border="1">';
echo '<tr><th>Понедельник</th><th>Вторник</th><th>Среда</th><th>Четверг</th><th>Пятница</th><th>Суббота</th><th>Воскресенье</th></tr>';

foreach ($weeks as $week) {
    echo '<tr>';
    for ($day = 1; $day <= 7; $day++) {
        echo '<td>' . ($week[$day] ?? '') . '</td>';
    }
    echo '</tr>';
}

echo '</table>';
?>

Фрагмент: https://onlinephp.io/c/5a2b8

Ответ или решение

Чтобы отобразить все даты года, сгруппированные еженедельно, мы можем использовать более простой подход, который не требует использования объектов DateTime. Ниже приведено примерное решение на PHP, которое демонстрирует, как выводить даты в виде таблицы, где каждая строка соответствует неделе, а каждый столбец – дню недели.

Полный код на PHP:

<?php

// Устанавливаем начальную и конечную даты для года
$year = 2024; // Замените на желаемый год
$startDate = mktime(0, 0, 0, 1, 1, $year);
$endDate = mktime(0, 0, 0, 12, 31, $year);

// Создаем массив для недель
$weeks = [];

// Переменная для текущей даты
$currentDate = $startDate;

// Идем по каждой дате в году
while ($currentDate <= $endDate) {
    $weekNumber = date('W', $currentDate); // Получаем номер недели
    $dayOfWeek = date('w', $currentDate); // Получаем номер дня недели (0 - воскресенье, 6 - суббота)

    // Сохраняем дату в массив по номеру недели и дню недели
    $weeks[$weekNumber][$dayOfWeek] = date('Y-m-d', $currentDate);

    // Переходим к следующему дню
    $currentDate = strtotime('+1 day', $currentDate);
}

// Выводим даты в виде HTML-таблицы
echo '<table border="1">';
echo '<tr><th>Понедельник</th><th>Вторник</th><th>Среда</th><th>Четверг</th><th>Пятница</th><th>Суббота</th><th>Воскресенье</th></tr>';

foreach ($weeks as $week) {
    echo '<tr>';
    for ($day = 0; $day <= 6; $day++) {
        echo '<td>' . ($week[$day] ?? '') . '</td>'; // Выводим дату или пустую ячейку
    }
    echo '</tr>';
}

echo '</table>';
?>

Объяснение кода:

  1. Инициализация:

    • Задаем год, с которого начнем (в данном случае 2024).
    • Определяем начальную и конечную даты с помощью функции mktime.
  2. Цикл по датам:

    • С помощью цикла while продолжаем до тех пор, пока текущая дата не превышает конец года.
    • Внутри цикла рассчитывается номер недели и день недели для текущей даты.
    • Дата сохраняется в массиве $weeks по соответствующему номеру недели и дня недели.
  3. Вывод в таблицу:

    • Создаём HTML-таблицу, которая содержит строки для каждой недели и ячейки для каждого дня недели.
    • Используем цикл для обхода массива недель и вывода соответствующих дат.

Таким образом, вы получите таблицу с датами, сгруппированными по неделям, где каждый день будет представлен в отдельной ячейке. Вы можете дополнительно стилизовать таблицу по своему усмотрению с помощью CSS.

Оцените материал
Добавить комментарий

Капча загружается...