Pero antes, algunas correcciones previas
En la línea 14 de la versión 0.1 de index.php, dice:echo "<h3>".traducir(date('l d \d\e F \d\e Y',$_GET['fechaactual']))."</h3>";Cambiando
date('l d \d\e F...') por date('l j \d\e F...') se consigue que los números de día menores a 10 se muestren sin el cero de la izquierda.También agregué la secuencia de caracteres de nueva línea (
\n) en lugares específicos de las cadenas de código html, con el solo fin de que cuando se vea el código de la página desde el navegador, éste se muestre más prolijo y no todo de corrido.Finalmente, borré las líneas 13 y 17 de la versión 0.1 de index.php, que lo que hacían era, respectivamente, abrir y cerrar una caja
div para centrar la fecha del día seleccionado. Voy a dejar lo relacionado con la presentación para hacerlo más adelante, con hojas de estilo (CSS) externas.El mensil
Ahora sí, vamos con el código para crear el mensil que incluye al día seleccionado.El siguiente es el código que escribí luego de la línea 16 de la versión 0.1 de index.php:
echo "\n<table>\n";
echo "<tr><th colspan='7'>".ucfirst(traducir(date('F \d\e Y',$_GET['fechaactual'])))."</th></tr>\n";
echo "<tr><th>Do</th><th>Lu</th><th>Ma</th><th>Mi</th><th>Ju</th><th>Vi</th><th>Sa</th></tr>\n";
echo "<tr>";
$primerDiaMes=mktime(0,0,0,date("m",$_GET['fechaactual']), '1',date("Y",$_GET['fechaactual']));
for ($i=1;$i<=date('w',$primerDiaMes);$i++)
{ echo "<td></td>"; }
$restoPrimeraSemana=8-$i;
for ($a=1;$a<=$restoPrimeraSemana;$a++)
{echo "<td>".$a."</td>";}
echo "</tr>\n<tr>";
$diasDelMes=date('t',$primerDiaMes);
$i=($i*-1) + 9;
$y=1;
for ($i;$i<=$diasDelMes;$i++)
{ echo "<td>".$i."</td>";
if (($y%7=="0") && ($i==$diasDelMes)) { }
elseif (($y%7=="0") && ($i<$diasDelMes)) { echo "</tr>\n<tr>"; }
$y++;
}
$y--;
$i--;
if (($y%7!="0") && ($i==$diasDelMes)) {
$ultimoDiaMes=mktime(0,0,0,date("m",$_GET['fechaactual']), $diasDelMes,date("Y",$_GET['fechaactual']));
$restoUltimaSemana= (date('w',$ultimoDiaMes) * -1) + 6;
for ($i=1;$i<=$restoUltimaSemana;$i++)
{ echo "<td></td>"; }
}
echo "</tr>\n";
echo "</table>\n";
Aquí va la explicación del código:
- La línea 1 abre la tabla. La etiqueta
<table>queda rodeada por dos secuencias de caracteres de nueva línea (\n). De ahora en más, se verá varias veces, en las ocurrencias de código html, esta secuencia, con el solo fin de obtener un código más prolijo. - Con el código de la línea 2:
- Se abre la primera fila (
<tr>). - Se abre una celda de cabecera que ocupa 7 columnas de ancho (
<th colspan='7'>). - Con la función date se obtiene el mes y el año (
'F \d\e Y') de la fecha que se está consultando ($GET_['fechaactual']).
Con la funcióntraducir(anteriormente creada e incluida desdefunciones.php) se traduce al español el nombre del mes.
Con la función ucfirst se cambia la primera letra del mes a mayúsculas.
Finalmente, se cierra la celda y la fila.
- Se abre la primera fila (
- En la línea 3 se imprime el código html para crear la segunda fila, son sus 7 celdas de cabecera, con la primeras letras de cada día de la semana en cada una.
- La línea 4 abre la tercera fila (la primera fila -semana- del mes propiamente dicho).
- En la línea 5 se define la variable
$primerDiaMes, conteniendo el tiempo unix (mktime) del primer día ('1') del mes (date("m",$_GET['fechaactual'])) y año (date("Y",$_GET['fechaactual'])) seleccionados. - Las líneas 6 y 7 son un bucle for, que define un contador
$icon valor "1", al que le va agregando uno ($i++) mientras$isea menor o igual adate('w',$primerDiaMes)(o sea, el día de la semana correspondiente al primer día del mes, representado por "0" para el domingo, "1" para el lunes y así hasta "6" para el sábado). Por cada vez que la condición sea válida en el bucle, se imprime una celda vacía (<td></td>).
O sea, si el primer día del mes es un domingo, el valor dedate('w',$primerDiaMes)será "0" y como el contador$icomienza en "1", no se cumle la condición$i<=date('w',$primerDiaMes)y, por lo tanto, no se genera ninguna celda vacía.
Por otra parte, si, por ejemplo, el primer día del mes es un jueves, el valor dedate('w',$primerDiaMes)será "4" y como el contador$icomienza en "1", la condición$i<=date('w',$primerDiaMes)se dará 4 veces y, por ende, generará 4 celdas vacías (correspondientes al domingo, lunes, martes y miércoles de la primera semana). - En la línea 8 se define la variable
$restoPrimeraSemana, cuyo conteniendo es el resultado de la resta8-$i. El valor de esta variable se corresponderá con la cantidad de días en la primera semana del mes. Siguiendo con los ejemplos del punto anterior, si el primer día del mes es domingo, el valor de$iseguirá siendo "1", tal cual se definió en un principio, ya que la condición del bucle de la linea 6 no se cumplió y no le modificó el valor a$i. Entonces, el valor de$restoPrimeraSemanaserá "7" (el resultado de 8-1); esto es, la primera semana del mes tiene 7 días.
Ahora, si el mes empieza en jueves, el valor de$iserá "5" (ya que por cada una de las 4 veces que se cumplió la condición establecida en la línea 6, se le sumó "1" al valor original de$i) y el valor de$restoPrimeraSemanaserá "3" (el resultado de 8-5); o sea los tres días (jueves, viernes y sábado) que tendrá la primera semana del mes dado. - En las líneas 9 y 10 se define un nuevo bucle for, que define un contador
$acon valor "1", al que le va agregando uno ($a++), mientras$asea menor o igual a$restoPrimeraSemana(o sea, la cantidad de días de la primera semana del mes). Por cada vez que la condición sea válida en el bucle, se imprime una celda con el número correspondiente ("<td>".$a."</td>"). - En la línea 11 se cierra la tercera fila (la de la primera semana, que se había abierto en la línea 4) con
</td>y se abre la cuarte fila (la de la segunda semana) con<td>. Separados ambos por una secuencia de caracteres de nueva línea (\n), por el mismo motivo ya expuesto en la explilcación de la línea 1. - En la línea 12 se define la variable
$diasDelMesque, mediante el uso de la función date con el carácter de formato't', guarda el número de días del mes dado (en este caso el mes al que pertenece el tiempo unix almacenado en$primerDiaMes). - A continuación se necesita una variable que almacene el número del día del domingo con el que comienza la segunda semana del mes. Para ello, se utiliza el valor previo de
$i, que era:- "1" si el primer día del mes es domingo (en cuyo caso, el domingo siguiente, o sea, el primer día de la segunda semana, sería el "8").
- "2" si el primer día del mes es lunes (entonces, el domingo siguiente es "7").
- "3" si el primer día del mes es martes (entonces, el domingo siguiente es "6").
- "4" si el primer día del mes es miércoles (entonces, el domingo siguiente es "5").
- "5" si el primer día del mes es jueves (entonces, el domingo siguiente es "4").
- "6" si el primer día del mes es viernes (entonces, el domingo siguiente es "3").
- "7" si el primer día del mes es sábado (entonces el domingo siguiente es "2").
$i, como el resultado de multiplicar el valor previo de$ipor "-1" y sumarle "9" y obtener así el número del domingo con el que comienza la segunda semana. - En la línea 14 se define una variable
$ycon valor "1", para usar como una especie de contador en la línea 17. - Entre las líneas 15 y 20 se define un nuevo bucle for. En este caso, para el valor de
$idefinido en la línea 13, y mientras ese valor sea menor o igual a la cantidad de días del mes definidos en la línea 12 ($i<=$diasDelMes), le agrega "1" a$i.
Lo primero que hace cuando se cumple la condición establecida es imprimir una celda con el valor de$i(línea 16).
Luego, en la línea 17 verifica, con un if, si el valor de$y(el contador definido en la línea 14 y al que se le agrega "1" en la línea 19) es divisible entre 7 y si el valor de$ies IGUAL a$diasDelMes. Estas dos condiciones se cumplen sólo cuando el último día del mes es un sábado. Entonces, luego de ese último día se termina la tabla, sin necesidad de agregar celdas vacías. Así que, en caso que se cumplan las dos condiciones, no hace nada (por eso no hay nada entre los corchetes curvos).
Si las condiciones de la línea 17 no se cumplen, en la línea 18, con un elseif verifica si el valor de$yes divisible entre 7 y si el valor de$ies MENOR a$diasDelMes. Estas dos condiciones sólo se cumplen cuando se llega a un sábado (el séptimo día de la semana, o sea, la séptima celda de la fila) que NO es el último día del mes. En caso que se den estas dos condiciones, imprime el cierre de esta fila y la apertura de la siguiente ("</tr>\n<tr>").
Mientras no se den esas condiciones establecidas en las líneas 17 y 18, y mientras$i<=$diasDelMesseguirá imprimiendo celdas con el correspondiente número de día como muestra la línea 16 ("<td>".$i."</td>"). - Con todo lo hecho hast a ahora, la tabla está prácticamente lista. Sólo falta crear las celdas vacías que sean necesarias para completar la última fila -semana- de la tabla. Para ello se utiliza un procedimiento análogo al utilizado para crear las celdas vacías en la primera semana del mes.
Pero, primero, en las líneas 21 y 22 se le resta "1" a las variables$yy$iporque en los bucles que se las utilizó previamente se les sumaba 1 luego de verificar que se cumpliera la condición, por lo que ambas terminaron con el último valor utilizado +1. - En la línea 23 se verifica, con un if, si el valor de
$yNO es divisible entre 7 y si el valor de$ies IGUAL a$diasDelMes. Estas dos condiciones se cumplen sólo cuando el último día del mes NO es un sábado. Por lo que sí es necesario agregar celdas vacías para completar la última fila. En caso que se cumplan las dos condiciones, se ejecuta el código de las líneas 24 a 27. - En la línea 24 se define la variable
$ultimoDiaMes, conteniendo el tiempo unix (mktime) del último día ($diasDelMes) del mes (date("m",$_GET['fechaactual'])) y año (date("Y",$_GET['fechaactual'])) seleccionados. - En la línea 25 se define la variable
$restoUltimaSemanaque va a contener la candidad de celdas vacías que tiene que llevar la última fila. Para ello, condate('w',$ultimoDiaMes)obtiene un número que representa el día de la semana del último día del mes (representado por "0" para el domingo, "1" para el lunes y así hasta "6" para el sábado). A ese número, se lo multiplica por "-1" y se le suma "6". Y, por la misma razón expuesta en la explicación de la línea 13, se guarda la variable$restoUltimaSemanala candidad de celdas vacías que tiene que llevar la última fila. - Las líneas 26 y 27 contienen el último bucle for, que define un contador
$icon valor "1", al que le va agregando uno ($i++), mientras$isea menor o igual a$restoUltimaSemana(o sea, la candidad de celdas vacías que tiene que llevar la última fila). Por cada vez que la condición sea válida en el bucle, se imprime una celda vacía ("<td></td>"). - Por último, en la línea 29 se cierra la última fila (
"</tr>") y en la 30 se cierra la tabla ("</table>").
Además, el código html5 generado por este script es válido, según http://html5.validator.nu/.

