El otro día me vinieron con un problema, necesitaba restar dos fechas para conocer la diferencia en minutos entre ellas, me vinieron a la mente varias soluciones directamente en la consulta SQL, pero el problema tenía una trampa, las fechas estaban en formato VARCHAR (¡horror!) y guardadas de dos maneras distintas, con este aspecto “21 de enero de 2013 15:35:33 GMT+01:00” y este otro “21 de enero de 2013 15:37:43“, o sea algunas venía con el GMT+01:00 y otras no.
Pues bien, ya tenía un pequeño reto para esa tarde, seguramente haya varias soluciones a este problema, yo aquí expondré la que se me ocurrió a mi
Una vez olvidada toda solución en la consulta SQL (¡lastima!, siempre que puedas resolver tu problema directamente en BBDD, jamás lo hagas en el código), esperé que PHP fuera mi aliado
Lo primero de todo, había que volver cristianas esas fechas, la programación no es magia, no puedes decirle réstame 21 de enero de 2013 15:35:33 menos 21 de enero de 2013 15:37:43 y dame como resultado 2 minutos, así que la función que me salió en ese momento de inspiración fue la siguiente:
/*
Función que transforma una fecha en formato "dd de mm de aaa hh:mm:ss GMT+01:00" a formato "m/dd/aaahh:mm:ss"
*/
function format_date($fecha) {
$fuera_gmt = str_replace("GMT+01:00", "", $fecha);
$fuera_de = str_replace("de", "/", $fuera_gmt);
$fuera_espacios = str_replace(" ", "", $fuera_de);
$meses = array("enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre");
for($i=0; $i<12;$i++) {
$busca_mes = strpos ($fuera_espacios, $meses[$i]);
if ($busca_mes !== false) {
$convertir_mes = str_replace($meses[$i], $i+1, $fuera_espacios);
}
}
$fecha_split = split("/", $convertir_mes);
$fecha_formateada = $fecha_split[1] . "/" . $fecha_split[0] . "/" . $fecha_split[2];
return $fecha_formateada;
}
Lógicamente es una función adaptada al problema en concreto, por eso procuro quitar los GMT, transformar los “de” en “/” y los meses en su correspondencia numerica (enero es 01, diciembre es 12), así que usando como base esta función, deberás cambiarla para que convierta desde el formato de tus fechas
Una vez que tenemos convertida la horripilante fecha 21 de enero de 2013 15:35:33 GMT+01:00 en algo más aceptable como 01/21/201315:35:33, el problema se vuelve más sencillo, ya podemos restar fechas con ese formato para conocer la diferencia entre ellas, en este caso la función salió una cosa como esta:
/*
Función que recibiendo dos fechas, nos devuelve los minutos de diferencia entre ellas
*/
function restaFechas($fecha_principal, $fecha_secundaria){
//Formato
$faux1 = format_date($fecha_principal);
$faux2 = format_date($fecha_secundaria);
//Fecha a Timestap de Unix
$fecha1 = strtotime($faux1);
$fecha2 = strtotime($faux2);
//Comprobar que una fecha es mayor que la otra para la resta
if ($fecha1 < $fecha2) {
$tmp = $fecha2;
$fecha2 = $fecha1;
$fecha1 = $tmp;
}
$resultado = ($fecha1 - $fecha2);
$resultado = $resultado / 60; //Paso a minutos
$resultado = round($resultado); //Redondeo
return $resultado;
}
A esta función, restaFechas, es a la que hay que llamar para que nos devuelva la diferencia entre las dos fechas, desde la cual llamamos a la otra función format_date y después una vez convertidas a la fecha en formato UNIX con la apreciada función PHP strtotime, podamos restarlas.
Como en este caso en concreto queremos que nos de el resultado en minutos dividimos el resultado de la resta por 60, si quieres que la diferencia nos la muestre en horas, se divide dos veces por 60 (/60/60), o si las fechas son tan alejadas que te merece más la pena la diferencia en días, a parte de dos veces por 60, divides también por 24 (/60/60/24).
Espero que os sea de ayuda este ejemplo

