Calcular días entre dos fechas con PHP

  • Por
Script PHP para calcular los días de diferencia que hay entre dos fechas.
A veces necesitamos saber los días que han transcurrido entre dos fechas. Con PHP podemos hacer esa tarea fácilmente, simplemente restando el valor timestamp de las dos fechas y convirtiendo a días. Lo explicaremos paso a paso en este taller.

El ejercicio es muy sencillo. Vamos a obtener los valores timestamp de las dos fechas. (Recordar que los timestamp son los segundos que han pasado desde las cero horas del 1 de enero de 1970) Como los dos timestamps son una cantidad de segundos, no tenemos más que restarlos para obtener los segundos de diferencia entre las dos fechas. Luego se trataría de convertir esos segundos en días para obtener el dato que estamos buscando.

Veamos entonces la manera de obtener un timestamp de una fecha. Entre las funciones de fechas de PHP hay varias que nos pueden servir para trabajar con timestamp, pero nosotros tenemos que utilizar una en concreto llamada mktime(). Esta función recibe varios parámetros:

mktime ( [int hora [, int minuto [, int segundo [, int mes [, int dia [, int anyo [, int es_dst]]]]]]] )

El primer parámetro es la hora, luego los minutos y segundos. Luego los meses, días y años. Con todos esos valores nos devuelve el timestamp de una fecha cualquiera. Podemos omitir parámetros y en ese caso tomará los valores de la fecha actual del servidor.

El código para obtener los timestamp de un par de fechas inventadas podría ser algo como el siguiente:

//defino fecha 1
$ano1 = 2006;
$mes1 = 10;
$dia1 = 2;

//defino fecha 2
$ano2 = 2006;
$mes2 = 10;
$dia2 = 27;

//calculo timestam de las dos fechas
$timestamp1 = mktime(0,0,0,$mes1,$dia1,$ano1);
$timestamp2 = mktime(0,0,0,$mes2,$dia2,$ano2);


Luego, podríamos restar los timestamp y convertir los segundos en días:

//resto a una fecha la otra
$segundos_diferencia = $timestamp1 - $timestamp2;
//echo $segundos_diferencia;

//convierto segundos en días
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);

Para convertir los segundos en días, como se ha podido observar en el código, hay que dividir entre el número de segundos de un día. (60 segundos de un minuto, por los 60 minutos de una hora, por las 24 horas de un día).

Ahora bien, con un código como el anterior, el valor de los días de diferencia puede tener decimales y ser negativo. Nosotros queremos un número de días entero y positivo. Entonces todavía tendremos que hacer un par de operaciones matemáticas. Primero quitar el signo negativo y luego quitar los decimales.

//obtengo el valor absoulto de los días (quito el posible signo negativo)
$dias_diferencia = abs($dias_diferencia);

//quito los decimales a los días de diferencia
$dias_diferencia = floor($dias_diferencia);


Los decimales los quitamos simplemente redondeando hacia abajo. Puesto que si tenemos un número decimal de días no ha llegado a un día completo y no nos interesa contabilizarlo.

El código completo se puede ver a continuación:

<?
//defino fecha 1
$ano1 = 2006;
$mes1 = 10;
$dia1 = 2;

//defino fecha 2
$ano2 = 2006;
$mes2 = 10;
$dia2 = 27;

//calculo timestam de las dos fechas
$timestamp1 = mktime(0,0,0,$mes1,$dia1,$ano1);
$timestamp2 = mktime(4,12,0,$mes2,$dia2,$ano2);

//resto a una fecha la otra
$segundos_diferencia = $timestamp1 - $timestamp2;
//echo $segundos_diferencia;

//convierto segundos en días
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);

//obtengo el valor absoulto de los días (quito el posible signo negativo)
$dias_diferencia = abs($dias_diferencia);

//quito los decimales a los días de diferencia
$dias_diferencia = floor($dias_diferencia);

echo $dias_diferencia;
?>

Autor

Miguel Angel Álvarez

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

Vlad

26/3/2007
teniendo los segundos que existen entre las dos fechas, puedes obtener cualquier cosa: dias, minutos, meses, años, etc; solo es cuestion de saber las equivalencias.

tachys

21/1/2008
Existe un error en el codigo, la funcion floor no redondea correctamente, la correcta seria la funcion round.
Este script lo prueba
<?php
$FechaIn="2008-12-31";//colocar un dia antes de la fecha del equipo donde se vaya a probar
$fecha_in_reserva = strtotime($FechaIn);//pasamos fecha a formato unix
for($n=0;$n<=365;$n++)
{
$FechaOut =date("Y-m-d", mktime(0, 0, 0, date("m") , date("d")+$n, date("Y")));
$fecha_out_reserva = strtotime($FechaOut);//pasamos fecha a formato unix
$dias_unix = $fecha_out_reserva - $fecha_in_reserva;//obtenemos numero de dias en formato unix

//obtenemos numero de dias en formato normal con floor descomentar para ver con floor
//y comentar la linea de round
//$dias = floor($dias_unix/86400);//linea de floor

//obtenemos numero de dias en formato normal con round descomentar para ver con round
//y comentar la linea de floor
$dias = round($dias_unix/86400);
$diasreal =$n+1;
echo 'Fecha inicio '.$FechaIn.' Fecha fin '.$FechaOut.' dias verdaderos '.$diasreal.'='.$dias.'dias coontados';
if ($dias!=$diasreal)
{
echo 'EROOORRRRRRRRRRRRRR';
}
echo '
<br/>';
}
?>

visof

12/2/2009
Para saber el numero de semanas se puede utilizar una constante

formato fecha: aaaa-mm-dd

$c = strtotime($fecha_final) - strtotime($fecha_inicial);
$semanas = ($c / 604800);

Nico

09/5/2009
diferencia entre floor o round
Muy bueno el script.
La diferencia entre usar floor o round depende de lo que busquemos.
Ejemplo:
Si el resultado da 2.6 usaremos floor si necesitamos la cantidad de dias completos(2 en este caso), en cambio si necesitamos un valor aproximado sin precision podemos usar round y asi nos daria 3.
Saludos.

argentina

02/8/2009
barbaro
buenisimo me sirvio mucho muy bien explicado!!

muchas gracias x el articulo!

kalep

22/9/2009
Solucion mas facil
La manera mas facil es convertir la fecha a calendario Juliano, el cual convierte la fecha en calendario juliano, despues simplemente resta los numeros y obtendras el numero de dias exactos.
$jul1=juliantojd(9,25,2002);
$jul=juliantojd(11,25,2002);
echo '->'."$jul",' dias '.($jul-$jul1);
tambien puedes sumar los dias al dia juliano y convertirlo a la fecha deseada
echo 'Juliano 1 '.jdtojulian(2452556);
echo ' juliano '.juliantojd(9,25,2002);
Os espero les haya servido esta solucion, es la mas facil

Esteban Novo

25/11/2009
Una opción mas prolija
function GetCountDaysBetweenTwoDates($DateFrom,$DateTo){

$HoursInDay = 24;
$MinutesInHour = 60;
$SecondsInMinutes = 60;
$SecondsInDay = (($SecondsInMinutes*$MinutesInHour)*$HoursInDay );
return intval(abs(strtotime($DateFrom) - strtotime($DateTo))/$SecondsInDay);
}

basara

28/12/2009
Excelente Post
men te felicito por este post tan bueno me reculto para validad lo que necesitaba no queria matarme tanto la cabeza y tu me la facilitastes graxx por todo

Murriel

19/1/2010
Bueno
Super bueno tu script.

juanp21

26/5/2010
Felicitaciones!
Muchas gracias a todos los que hacen posible esta web, me ha servido de mucha ayuda a la hora de empezar en este interesante mundo de la programacion para la web y el desarrollo se paginas web.

Felix

23/6/2010
Diferencia entre dos fechas dadas
Hola Buenas tardes.!!! tengo un proble, necesito saber como calcular los dias de diferencia entre dos fechas indicadas por el usuario utilizando los input.

Agradeceria me ayudaras con este pequeño problema ya q soy novato en php.

Gracias.!!!

Franklin Lanz

19/8/2010
mmmmm
Muy bueno pero si el calculo pasa de 30 dias no lo realiza, siempre queda en 30 cuando son por ejemplo 60

mbt

07/9/2010
genial este sitio!!
quiero felicitarlos por este sitio tan completo y util para todos los que hemos empezado a programar web, los felicito y espero que sigan on line por muuucho tiempo mas!!!!!!

aldo1982

24/9/2010
encapsular en funcion
hola yo lo arme en una funcion que quedaría asi

function restar_dos_fechas($fecha1, $fecha2) {
// fechas en formato AAAA/MM/DD
//defino fecha 1
$f1 = explode("-",$fecha1);
$ano1 = $f1[0];
$mes1 = $f1[1];
$dia1 = $f1[2];

//defino fecha 2
$f2 = explode("-",$fecha2);
$ano2 = $f2[0];
$mes2 = $f2[1];
$dia2 = $f2[2];

//calculo timestam de las dos fechas
$timestamp1 = mktime(0,0,0,$mes1,$dia1,$ano1);
$timestamp2 = mktime(4,12,0,$mes2,$dia2,$ano2);

//resto a una fecha la otra
$segundos_diferencia = $timestamp1 - $timestamp2;
//echo $segundos_diferencia;

//convierto segundos en días
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);

//obtengo el valor absoulto de los días (quito el posible signo negativo)
//$dias_diferencia = abs($dias_diferencia);

//quito los decimales a los días de diferencia
$dias_diferencia = floor($dias_diferencia);

return $dias_diferencia;
}


salu2 aldo

Enrique

02/3/2011
Muy bueno
Hola, es muy bueno el tema, sencillo pero completo :)
Solo una duda, por que sale en el mktime en el primer codigo 0,0,0 en las dos lineas y luego en el codigo final en el mktime una linea 0,0,0 y en la otra 4,12,0

Drakkar

06/4/2011
no me parece el resultado
estuve leyendo en otros foros y segun parece esto
$dias_diferencia = $segundos_diferencia / (60 * 60 * 24);

debemos de cambiarlo por $dias_diferencia = $segundos_diferencia / (60 * 60 * 24*1000);

ya que son milisegundos lo que obtenemos al restar los valores timestamp y no segundos.

con esto el valor me dio correctamente, pero si estoy equivocado háganmelo saber XD

Paquirri

10/1/2012
Error en cálculo de fechas
Este método (obtener segundos de ambas fechas, restarlas y dividir entre (24*60*60) funciona bien, pero hay algunas fechas que me dan error.

Ej: 11 al 14 de marzo de 2012.. El resultado es 2.9, si haces floor o intval, queda en 2 días de diferencia, siendo que son 3.

En tu segundo ejemplo, haces el maketime de la segunda fecha a las 12 horas y 4 minutos, por lo que da correcto 3 días de diferencia.. creo que sería interesante detectar la razón exacta (tal vez por años biciestos?) y tener un script que sea infalible..

alguna idea?

Larry Hans

27/2/2012
Ejemplo practico
Este artículo es un gran material sobre PHP, que en general, pueden aplicar en conjunto, con el analisis de un contador de días (tipo http://hackingballz.com/contador-de-dias-online/) donde se utilizan las funciones del mismo, para determinar la antiguedad en días de una fecha.

Rodrigo

30/10/2012
Excelente! salvo un detalle
Me sirvio casi enseguida, otros códigos no me habían servido por el tema de que a fecha se guarda en formato "AAAA-MM-DD HH:MM:SS". Este si me sirvio muchísio. Muchas gracias. El detalle es que en esta línea hay que arreglarla y dejarla asi:

$timestamp2 = mktime(0,0,0,$mes2,$dia2,$ano2);

(creo que tiene otros números donde van los ceros).

uTombou

10/1/2013
Una Solución mas simple...
Hola, saludos a todos...
Primero que nada felicito al autor del post por el aporte...

Y bueno nada en esta oportunidad quisiera completar la idea con una pequeña solución que se me ocurrió implementando las bondades del strtotime del php5.

Aquí se las dejo:

function dias_transcurridos($fecha_inicial, $fecha_final){
return floor(abs((strtotime($fecha_inicial)-strtotime($fecha_final))/86400));
}

Espero les sirva... =)

Panita

14/5/2014
Excelente
Gracias por el aporte, justo lo q estaba buscando :pulgar arriba: