Php, strtotime y los meses que te parieron(?)
Después de un par de horas de Divertirme como un geek logré solucionar un problemita que encontré con Php, la función strtotime y la necesidad de sumarle 1 mes a una fecha dada.
La cuestión puedo ejemplificarla asi:
El usuario ingresa una fecha: 2007-01-03
Yo a eso necesito sumarle 1 mes: $nuevafecha = date('Y-m-d,strtotime('2007-01-03 +1 month');
Resultado: 2007-02-03
Hasta ahi, todo bien.
PERO, que pasa con febrero? eh?
El usuario ingresa una fecha: 2007-01-31
Yo a eso necesito sumarle 1 mes: $nuevafecha = date('Y-m-d,strtotime('2007-01-31 +1 month');
Resultado: 2007-03-02
Ahi está el problema. Una cosa es sumarle 1 mes y otra sumarle 30 días, don php(?).
Este problema también se presentó con los meses que tienen 31 días y son seguidos de meses que tienen 30.
La solución que encontré (que se que no es la MÁS práctica generalmente pero que a mi proyecto le entró con vaselina) es hacer la suma y chequear si el mes que dio de resultado es igual al mes original +1.
o sea:
if(date('m',strtotime($nuevafecha)) != (date('m',strtotime('2007-01-31')))+1)
Luego hice un hermoso loop en el cual le desconté un día a $nuevafecha siempre y cuando el mes sea diferente a mes +1.
while(date('m',strtotime($nuevafecha)) != $mescorrecto)
{
$nuevafecha = date('Y-m-d',strtotime("$okdate -1 day"));
}
donde $mescorrecto = ‘02′ (en este caso)
2 hermosas horitas insultando a los programadores de php, pero fue divertido.




O podes ahorrarte loops y usar date(”t”) que te dice la cantidad de dias del mes (aka, el ultimo dia del mes).
ah, miralo vos al loco ese(?)
gracias
y yo que me quejo de Java…
Todos nos quejamos de Java, no te preocupes.
Y si lo hacías con mktime?
descomponiendo la fecha de entrada, y poniendolo en cada parametro, y en el del mes le mandas un +1.
Porque al 31 de enero te mandaria al 31 de Febrero, cosa que… ehm… ¿no va?
El mktime te “acomoda” los días y meses. Cosa que si le mandas el nro de mes 13 en realidad te devuelve el mes 1 del año siguiente.
Pero igualmente acabo de probar
echo date(’Y-m-d’, mktime(0, 0, 0, 2, 31, 2007));
y me devolvió “2007-03-03″ igual que con la función que estaban teniendo problemas, asique no me den bola…
Que viva timelocal_nocheck de perl!
Vos queres que si el usuario ingresa 2007-01-31, te devuelva 2007-02-28 ? Si es asi, algo asi tendrias que haber hecho:
[php]
function sumar_meses( $fecha, $meses )
{
$actual = getdate( $fecha );
$siguiente = getdate( mktime( $actual["hours"], $actual["minutes"], $actual["seconds"],
$actual["mon"] + $meses, $actual["mday"], $actual["year"] ) );
if ( $siguiente["mon"] == (($actual["mon"] + $meses - 1) % 12) + 1 ) {
return mktime( $siguiente["hours"], $siguiente["minutes"], $siguiente["seconds"],
$siguiente["mon"], $siguiente["mday"], $siguiente["year"] );
} else {
return mktime( $siguiente["hours"], $siguiente["minutes"], $siguiente["seconds"],
$siguiente["mon"], 0, $siguiente["year"] );
}
}
// Le sumo 1
echo date(”r”, sumar_meses( strtotime(”2007-01-31″), 1 ) );
// Le resto 1
echo date(”r”, sumar_meses( strtotime(”2007-03-31″), -1 ) );
[/php]
Saludos =)