PHP y el error al restar fechas después del cambio de hora

partimos de una funcion en PHP que resta dias

function restadias($fecha,$dias){
	list( $dia, $mes, $year ) = split( '/', $fecha );
	//teniendo la fecha tenemos que obtener el lunes y el viernes de esa semana.
	$f=mktime(0 , 0, 0, (int)$mes  , (int)$dia, (int)$year);
	$sumadias=60*60*24*($dias);
	$l=$f-$sumadias;
		$dia1=date('j',$l);
	if ($dia1<10){
		$d="0".$dia1;
	}else{
		$d=$dia1;
	}
	$mes1=date('n',$l);
	if ($mes1<10){
		$m="0".$mes1;
	}else{
		$m=$mes1;
	}
	$year1=date('Y',$l);
	$nf   = $d."/".$m."/".$year1;
	
	return $nf;
}

Si vemos la función, lo que hace es partir la fecha de texto dd/mm/aaaa y obtener el valor en segundos con mktime, luego los días que va a restar los multiplica por el número de segundos del día y hace la resta, el resultado lo formatea otra vez en formato dd/mm/aaaa

Así para el ejemplo:

echo restadias("03/03/2016",1);

El resultado es o debería de ser 02/03/2016

Pero para restadias("28/03/2016",1) cuando debería de darnos el día 27 nos devuelve un fatídico 26/03/2016.


1459123200 - 86400  = 1459036800

Y todo por el cambio de hora, como la función realiza el mktime pasando 0 en horas, minutos y segundos, al restar 86400 segundos según la funcion $dia1=date('j',$l)
Y lo vemos mejor viendo la hora:

date("H",$l);

Donde parte de las 0 y nos devuelve 23.

para solucionarlo, modificamos la función restadias por:

function restadias($fecha,$dias){
	list( $dia, $mes, $year ) = split( '/', $fecha );
	//teniendo la fecha tenemos que obtener el lunes y el viernes de esa semana.
	$f=mktime(12 , 0, 0, (int)$mes  , (int)$dia, (int)$year);
	$sumadias=60*60*24*($dias);
	$l=$f-$sumadias;
		$dia1=date('j',$l);
	if ($dia1<10){
		$d="0".$dia1;
	}else{
		$d=$dia1;
	}
	$mes1=date('n',$l);
	if ($mes1<10){
		$m="0".$mes1;
	}else{
		$m=$mes1;
	}
	$year1=date('Y',$l);
	$nf   = $d."/".$m."/".$year1;
	
	return $nf;
}

Donde hemos puesto como hora las 12, asi nos evitamos el problema del cambio de hora, de 2 a 3 de la mañana.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

* Please enter the Biggest Number