Календарь на PHP

Основная проблема при формировании календаря заключается в том, что месяц, как правило, начинается с середины недели. Сам календарь представляет собой таблицу с количеством строк, равных количеству дней в неделе, и количеством столбцов, равных количеству недель в месяце, поэтому формирование календаря целесообразно проводить сразу в двухмерном массиве.

<?php
  setlocale ( LC_ALL, '' );
  // Название месяца
  echo '<h3>'.strftime( '%B' ).'</h3>';
  // Вычисляем число дней в текущем месяце
  $dayofmonth = date('t');
  // Счётчик для дней месяца
  $day_count = 1;

  // Первая неделя
  $num = 0;
  for( $i = 0; $i < 7; $i++ ) {
    // Вычисляем номер дня недели для числа
    $dayofweek = date('w', mktime(0, 0, 0, date('m'), $day_count, date('Y')));
    // Приводим к числа к формату 1 - понедельник, ..., 6 - суббота
    $dayofweek = $dayofweek - 1;
    if($dayofweek == -1) $dayofweek = 6;

    if($dayofweek == $i) {
      // Если дни недели совпадают, заполняем массив $week числами месяца
      $week[$num][$i] = $day_count;
      $day_count++;
    } else {
      $week[$num][$i] = '';
    }
  }

  // Последующие недели месяца
  while( true ) {
    $num++;
    for( $i = 0; $i < 7; $i++ ) {
      $week[$num][$i] = $day_count;
      $day_count++;
      // Если достигли конца месяца - выходим из цикла
      if( $day_count > $dayofmonth ) break;
    }
    // Если достигли конца месяца - выходим из цикла
    if( $day_count > $dayofmonth ) break;
  }
  // Какой сегодня день
  $today = date( 'j' );
  // Выводим содержимое массива $week в виде календаря
  echo '<table border="1" style="border-collapse:collapse" cellpadding="5" cellspacing="0">';
  for( $j = 0; $j < 7; $j++ ) {
    echo '<tr align="right">';
    for( $i = 0; $i < count($week); $i++ ) {
      if( !empty( $week[$i][$j] ) ) {
        if ( $week[$i][$j] == $today )
          echo '<td bgcolor="#DDDDDD">';
        else
          echo '<td>';
        // Если имеем дело с субботой и воскресеньем - подсвечиваем их
        if( $j == 5 || $j == 6 )
          echo '<span style="color:red">'.$week[$i][$j].'</span>';
        else
          echo $week[$i][$j];
        echo '</td>';
      } else {
        echo '<td>&nbsp;</td>';
      }
    }
    echo '</tr>';
  }
  echo '</table>';
?>

Чтобы изменить формат вывода календаря недель месяца с вертикального на горизонтальный - достаточно внести незначительные изменения в тот фрагмент кода, который отвечает за вывод сформированного массива в виде таблицы:

<?php
  setlocale ( LC_ALL, '' );
  // Название месяца
  echo '<h3>'.strftime( '%B' ).'</h3>';
  // Вычисляем число дней в текущем месяце
  $dayofmonth = date('t');
  // Счётчик для дней месяца
  $day_count = 1;

  // Первая неделя
  $num = 0;
  for( $i = 0; $i < 7; $i++ ) {
    // Вычисляем номер дня недели для числа
    $dayofweek = date('w', mktime(0, 0, 0, date('m'), $day_count, date('Y')));
    // Приводим к числа к формату 1 - понедельник, ..., 6 - суббота
    $dayofweek = $dayofweek - 1;
    if($dayofweek == -1) $dayofweek = 6;

    if($dayofweek == $i) {
      // Если дни недели совпадают, заполняем массив $week числами месяца
      $week[$num][$i] = $day_count;
      $day_count++;
    } else {
      $week[$num][$i] = '';
    }
  }

  // Последующие недели месяца
  while( true ) {
    $num++;
    for( $i = 0; $i < 7; $i++ ) {
      $week[$num][$i] = $day_count;
      $day_count++;
      // Если достигли конца месяца - выходим из цикла
      if( $day_count > $dayofmonth ) break;
    }
    // Если достигли конца месяца - выходим из цикла
    if( $day_count > $dayofmonth ) break;
  }
  // Какой сегодня день
  $today = date( 'j' );
  // Выводим содержимое массива $week в виде календаря
  echo '<table border="1" style="border-collapse:collapse" cellpadding="5" cellspacing="0">';
  for( $i = 0; $i < count($week); $i++ ) {
    echo '<tr align="right">';
    for( $j = 0; $j < 7; $j++ ) {
      if( !empty( $week[$i][$j] ) ) {
        if ( $week[$i][$j] == $today )
          echo '<td bgcolor="#DDDDDD">';
        else
          echo '<td>';
        // Если имеем дело с субботой и воскресеньем - подсвечиваем их
        if( $j == 5 || $j == 6 )
          echo '<span style="color:red">'.$week[$i][$j].'</span>';
        else
          echo $week[$i][$j];
        echo '</td>';
      } else {
        echo '<td>&nbsp;</td>';
      }
    }
    echo '</tr>';
  }
  echo '</table>';
?>

Один комментарий

  1. alexey:

    Добрый день!
    Нашел скрипт календаря, который удобно встроился в сайт. Единственное “но” - 1 число всегда воскресенье, а, скажем, 14-е - всегда суббота.
    Как сделать так, чтобы после 30 или 31 числа месяца следующий месяц начинался с положенного дня недели, а не с воскресенья?
    В пхп я не специалист, но хотел бы разобраться. Если можно, напишите так же, как в вашем примере, с комментариями.

Оставьте свой отзыв