Mostrar calendario PHP II

  • Por
Segunda parte de la explicación de la función mostrar_calendario() para la práctica del calendario PHP.
En el artículo anterior comenzamos a explicar la función mostrar_calendario() que es el alma de nuestra práctica de calendario PHP.

Para continuar, vamos a empezar a escribir los números de los días, del 1 hasta el número de días que tenga el mes. Habrá que empezar, lógicamente, por el día 1, pero antes de escribirlo, debemos averiguar qué día de la semana es el día 1. Si se tratase de un viernes, por ejemplo, deberíamos dejar, en la primera fila, libres las casillas del lunes al jueves y a partir de del viernes empezar a colocar números de días.

Vamos a llevar la cuenta del día que tenemos que imprimir en pantalla con la variable $dia_actual.

También tenemos que crear una variable que valga el número de días que tiene el mes, para saber cuándo parar de escribir números en el calendario.

Estas serían las siguientes líneas de código para obtener todos los datos de control que estamos señalado.

//Variable para llevar la cuenta del dia actual
$dia_actual = 1;

//calculo el numero del dia de la semana del primer dia
$numero_dia = calcula_numero_dia_semana(1,$mes,$ano);

//calculo el último dia del mes
$ultimo_dia = ultimoDia($mes,$ano);

Nota: Acabamos de utilizar dos nuevas funciones:
  • Calcula_numero_dia_semana() para obtener el día de la semana del primer día del mes.
  • UltimoDia(), para saber cuantos días tiene el mes.
Estas funciones las podremos encontrar documentadas en un capítulo más adelante.

Ahora tenemos toda la información necesaria para escribir la primera fila de días en el calendario. Recordar que varias de las casillas de esta fila deben aparecer vacías porque el mes no tiene por qué empezar en lunes.

//escribo la primera fila de la semana
echo "<tr>";
for ($i=0;$i<7;$i++){
   if ($i < $numero_dia){
      //si el dia de la semana i es menor que el numero del primer dia de la semana no pongo nada en la celda
      echo '<td class="diainvalido"><span></span></td>';
   } else {
      echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
      $dia_actual++;
   }
}
echo "</tr>";


Vemos que no encierra ningún misterio, simplemente hacemos un bucle que se repetirá 7 veces, tantas como días de la semana. Dentro del bucle comprobamos si el día de la semana actual es menor que $numero_dia, donde guardábamos el número de la semana del primer día del mes.

Si no hay que escribir el día simplemente se coloca la celda vacía y si tengo que escribirlo se coloca el día actual en la celda y se incrementa en uno dicho día actual.

Para continuar, debemos escribir en el calendario todos los demás días del mes, continuando por donde lo hubiésemos dejado. Para ello utilizamos un simple bucle que recorre esos días mientras que no lleguemos al último día del mes.

//recorro todos los demás días hasta el final del mes
$numero_dia = 0;
while ($dia_actual <= $ultimo_dia){
   //si estamos a principio de la semana escribo el <TR>
   if ($numero_dia == 0)
      echo "<tr>";
   echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
   $dia_actual++;
   $numero_dia++;
   //si es el uñtimo de la semana, me pongo al principio de la semana y escribo el </tr>
   if ($numero_dia == 7){
      $numero_dia = 0;
      echo "</tr>";
   }
}


La única complejidad que puede tener este trozo de código es saber cuándo debemos escribir el principio y el final de la fila, con sus correspondientes <tr> y </tr>. Para éllo, vamos a llevar la cuenta, con $numero_dia, del día de la semana que estamos imprimiendo.

Si estamos al principio de la semana ($numero_dia = 0) entonces escribo el inicio de fila con <tr>; Si estamos al final de la fila ($numero_dia = 7) entonces pongo el final de la fila con </tr>.

Entre medias de cada iteración se incrementa el $día_actual (que lleva la cuenta de todos los días del mes) y el $numero_día (que indicábamos que servía para saber en qué parte de la fila estamos).

Las últimas líneas de código de la función las vemos ahora.

//compruebo que celdas me faltan por escribir vacias de la última semana del mes
for ($i=$numero_dia;$i<7;$i++){
   echo '<td class="diainvalido"><span></span></td>';
}

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


Simplemente escribo celdas vacías para las últimas casillas de la semana que acaba el mes donde no quedan días. Igual que al principio del calendario el primer día no tenía que estar en la primera casilla, el último día del calendario no tiene porque estar en la última casilla disponible.

Código completo de la función mostrar_calendario()

Ahora mostramos todo el código de la función mostrar_calendario(), para que se pueda ver de una manera global y analizar mejor su funcionamiento.

function mostrar_calendario($mes,$ano){
   //tomo el nombre del mes que hay que imprimir
   $nombre_mes = dame_nombre_mes($mes);
   
   //construyo la tabla general
   echo '<table class="tablacalendario" cellspacing="3" cellpadding="2" border="0">';
   echo '<tr><td colspan="7" class="tit">';
   //tabla para mostrar el mes el año y los controles para pasar al mes anterior y siguiente
   echo '<table width="100%" cellspacing="2" cellpadding="2" border="0"><tr><td class="messiguiente">';
   //calculo el mes y ano del mes anterior
   $mes_anterior = $mes - 1;
   $ano_anterior = $ano;
   if ($mes_anterior==0){
      $ano_anterior--;
      $mes_anterior=12;
   }
   echo '<a href="index.php?nuevo_mes=' . $mes_anterior . '&nuevo_ano=' . $ano_anterior .'"><span>-;</span></a></td>';
    echo '<td class="titmesano">' . $nombre_mes . " " . $ano . '</td>';
    echo '<td class="mesanterior">';
   //calculo el mes y ano del mes siguiente
   $mes_siguiente = $mes + 1;
   $ano_siguiente = $ano;
   if ($mes_siguiente==13){
      $ano_siguiente++;
      $mes_siguiente=1;
   }
   echo '<a href="index.php?nuevo_mes=' . $mes_siguiente . '&nuevo_ano=' . $ano_siguiente . '"><span>+</span></a></td>';
   //finalizo la tabla de cabecera
   echo '</tr></table>';
   echo '</td></tr>';
   //fila con todos los días de la semana
   echo '   <tr>
            <td width="14%" class="diasemana"><span>L</span></td>
            <td width="14%" class="diasemana"><span>M</span></td>
            <td width="14%" class="diasemana"><span>X</span></td>
            <td width="14%" class="diasemana"><span>J</span></td>
            <td width="14%" class="diasemana"><span>V</span></td>
            <td width="14%" class="diasemana"><span>S</span></td>
            <td width="14%" class="diasemana"><span>D</span></td>
         </tr>';
   
   //Variable para llevar la cuenta del dia actual
   $dia_actual = 1;
   
   //calculo el numero del dia de la semana del primer dia
   $numero_dia = calcula_numero_dia_semana(1,$mes,$ano);
   //echo "Numero del dia de demana del primer: $numero_dia <br>";
   
   //calculo el último dia del mes
   $ultimo_dia = ultimoDia($mes,$ano);
   
   //escribo la primera fila de la semana
   echo "<tr>";
   for ($i=0;$i<7;$i++){
      if ($i < $numero_dia){
         //si el dia de la semana i es menor que el numero del primer dia de la semana no pongo nada en la celda
         echo '<td class="diainvalido"><span></span></td>';
      } else {
         echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
         $dia_actual++;
      }
   }
   echo "</tr>";
   
   //recorro todos los demás días hasta el final del mes
   $numero_dia = 0;
   while ($dia_actual <= $ultimo_dia){
      //si estamos a principio de la semana escribo el <TR>
      if ($numero_dia == 0)
         echo "<tr>";
      echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
      $dia_actual++;
      $numero_dia++;
      //si es el uñtimo de la semana, me pongo al principio de la semana y escribo el </tr>
      if ($numero_dia == 7){
         $numero_dia = 0;
         echo "</tr>";
      }
   }
   
   //compruebo que celdas me faltan por escribir vacias de la última semana del mes
   for ($i=$numero_dia;$i<7;$i++){
      echo '<td class="diainvalido"><span></span></td>';
   }
   
   echo "</tr>";
   echo "</table>";
}

En el próximo artículo veremos la función que muestra el formulario para seleccionar otro mes y año en el calendario. Si lo deseamos, podemos Ver el calendario en funcionamiento.

Autor

Miguel Angel Alvarez

Miguel es fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Comenzó en el mundo del desarrollo web en el año 1997, transformando su hobby en su trabajo.

Compartir

Comentarios

Juan Carlos

13/2/2006
Para saber el último día del mes es mucho más simple utilizar la función date("t") que viene implementada en PHP.

Juan Carlos

13/2/2006
Para saber el último día del mes es mucho más simple utilizar la función date("t") que viene implementada en PHP.

Martin

24/10/2006

hice este codigo , mmm q creo q disminuye unas 2 lineas de codigo :)

while($dia_actual <= $ultimo_dia){
echo "<tr>";
for($i=0;$i<7;$i++){
if($numero_dia <= $i && $dia_actual <=$ultimo_dia){
echo "<td>".$dia_actual."</td> ";
$dia_actual++;
$numero_dia++;
}else{
echo "<td></td> ";
}
}
if($numero_dia== 7){
$numero_dia =0;
}
echo "</tr> ";

}echo "</table>";

gonzalo_rodriguez_vilches

27/4/2009
calendario
Hola me gustaria saber si puedo conectar este calendario con mysql

Rayaman

17/11/2009
Muy Buen Tutorial
Agradezco mucho que hayan puesto este manual de generar calendario, yo necesitaba uno y la verdad es que me sirvio de mucho, hice una combinacion trayendo la fecha de un calendar mootools y anexandola a este calendario resulto una buena combinación. Saludos y Gracias por este aporte.

Rodrigo

10/1/2013
Calendario PHP
Esta manera es mas fácil para el calendario

<?php
date_default_timezone_set('America/Argentina/Buenos_Aires');

if(!isset($_GET["month"]) or !isset($_GET["year"])){

$month=date("m");

$year=date("Y");
}else{

$month=$_GET["month"];

$year=$_GET["year"];
}

$total_days = date("t",strtotime($month."/01/".$year.""));

$nombre_mes = array("01" => "Enero", "02" => "Febrero", "03" => "Marzo", "04" => "Abril", "05" => "Mayo", "06" => "Junio", "07" => "Julio", "08" => "Agosto", "09" => "Septiembre", "10" => "Octubre", "11" => "Noviembre", "12" => "Diciembre",);

?>

<table width="100%" border="0">
<tr>
<td colspan="7" align="center">
<form action="" method="get" name="timeselector">
<select name="month" onchange="document.forms['timeselector'].submit();">
<?php
for($i=1;$i<=12;$i++){
if($i<10){ $m="0".$i;}else{$m=$i;}
if($m==$month){
echo'<option value="'.$m.'" selected="selected">'.$nombre_mes[$m].'</option>';
}else{
echo'<option value="'.$m.'">'.$nombre_mes[$m].'</option>';
}
}
?>
</select>
<select name="year" onchange="document.forms['timeselector'].submit();">
<?php
for($i=$year-5;$i<=$year+5;$i++){
if($i==$year){
echo'<option value="'.$i.'" selected="selected">'.$i.'</option>';
}else{
echo'<option value="'.$i.'">'.$i.'</option>';
}
}
?>
</select>
</form> </td>
</tr>
<tr>
<td align="center" valign="middle">Dom</td>
<td align="center" valign="middle">Lun</td>
<td align="center" valign="middle">Mar</td>
<td align="center" valign="middle">Mie</td>
<td align="center" valign="middle">Jue</td>
<td align="center" valign="middle">Vie</td>
<td align="center" valign="middle">Sab</td>
</tr>
<?php
$first_day=date("N",strtotime($month."/01/".$year.""));
if($first_day!=7){
for($i=0;$i<$first_day;$i++){
if($i==0){echo "<tr>";}
echo"<td align='center' valign='middle'></td>";
}
}
for($day=1;$day<=$total_days;$day++){
if(date("N",strtotime($month."/".$day."/".$year.""))==7){
echo"<tr><td align='center' valign='middle'>".$day."</td>";
}else{
if(date("N",strtotime($month."/".$day."/".$year.""))==6){
echo"<td align='center' valign='middle'>".$day."</td></tr>";
}else{
echo"<td align='center' valign='middle'>".$day."</td>";
}
}
}
?>
</table>