Recorrer un rango de fechas en php

Índice
  1. Introducción
  2. Convertir fecha a timestamp
  3. Como recorrer un rango de fechas

Introducción

Recientemente para un proyecto, necesitaba recorrer un rango de fechas en php, para realizar una serie de comprobaciones cada día de ese rango.

Investigando a ver cómo se podía hacer de manera sencilla, encontré un método que puede resultarnos muy útil.

Como comentaba en un post para calcular dias entre dos fechas, lo primordial es realizar la conversion a timestamp.

Convertir fecha a timestamp

Lo primero es convertir la fecha a formato timestamp con la función strtotime:

echo strtotime("dd-mm-aaaa");

en la que debemos sustituir “dd-mm-aaaa” por la fecha a convertir.

Si queremos obtener el timestamp de ahora mismo, es tan simple como hacer

echo strtotime("now");

Como recorrer un rango de fechas

Se trata de utilizar un bucle for de toda la vida, pero haciendo una conversión de las fechas a timestamp. Además, incrementaremos la variable en 86400 (el número de segundos de un día), de esta manera avanzamos día a día.

Por ejemplo, si queremos recorrer el rango de fechas del 25 de febrero de 2008 al 1 de abril de 2008, lo haríamos asi:

<?php
$fechaInicio=strtotime("25-02-2008");
$fechaFin=strtotime("01-04-2008");
for($i=$fechaInicio; $i<=$fechaFin; $i+=86400){
    echo date("d-m-Y", $i)."<br>";
}
?>

Con este método nos evitamos las comprobaciones por si es año bisiesto, numero de días por mes, etc. ¿Conocéis alguna otra manera de recorrer un rango de fechas que sea sencilla?. Si es así, dejar un mensaje, y así nos beneficiamos todos... ;D

¡Haz clic para puntuar esta entrada!
(Votos: 4 Promedio: 5)
  1. Sarai Santiago Sanchez dice:

    muy buenas noches, quiero implementar eso pero con horas, lo que pasa es que estoy creando una pagina web para solicitar citas medicas, quisiera que en mi formulario menú en donde tengo registrado mis horarios, me aparezcan para el primer paciente pues todos los horarios disponibles pero que después de que este aya registrado su cita, automáticamente se de de baja ese horario, se guarde en la base de datos y que se actualice de manera que cuando el segundo paciente ingrese a la pagina pues solo le aparezcan los horarios disponibles sin incluir el que ya está registrado en la base de datos, plis ayuda

    1. issux dice:

      Lo que tienes que hacer es dividir el problema en varias partes (inserción en la bd, mostrar las horas, formulario de inscripción a las citas) e ir resolviéndolo por partes. Es mucho mas sencillo de lo que parece, pero la clave esta en ir por partes resolviéndolo. En internet podrás encontrar todo lo que necesitas sobre inserción de base de datos, formularios, etc

  2. fdfdf dice:

    falta un parentesis en la segunda fila

    1. issux dice:

      Gracias, ya esta corregido ;D

  3. LUIS PUMARICRA DIAZ dice:

    Hola gracias por tu codigo, este es mi caso:

    $fechaInicio = strtotime("01-03-2011");
    $fechaFin = strtotime("31-03-2011");

    for($i=$fechaInicio; $i<=$fechaFin; $i+=86400){
    echo date("d-m-Y", $i)."";
    }

    ----

    si ejecuto eso, se genera el bucle y me sale:
    01-03-2011 hasta el 30-03-2011

    pero MARZO del 2011 no tiene 31 DIAS...?

    please ayudame... que debo de cambiar o agregar en el codigo..?

    1. issux dice:

      Buenas Luis.

      Es curioso, hay un desfase de 1/2h y por eso no muestra el dia 31. ¿Quizas sea por la combinacion de la zona horaria junto con el horario de verano?.

      En fin, para evitar eso, cambia la linea por
      $fechaFin = strtotime("31-03-2011 + 1 days");

      Con esto se arreglaria.

      Saludos.

      1. Anonymous dice:

        también se arregla con esto :

        $fechaInicio = strtotime("01-03-2011 00:00:00");
        $fechaFin = strtotime("31-03-2011 23:59:59");

        1. Juan Castillo dice:

          Es raro porque tengo este código
          <?php
          $fecha_inicial = strtotime("2019-04-01 00:00:00");
          $fecha_final= strtotime("2019-12-31 23:59:59");
          $cont = 1;
          echo date('Y-m-d',$fecha_inicial)."";
          echo date('Y-m-d',$fecha_final)."";
          for($i=$fecha_inicial; $i<=$fecha_final; $i+=86400){
          $fecha = date('Y-m-d G:i:s',$i);
          echo $i." :: ".$cont.".- ".$fecha."";
          $cont++;
          }
          ?>

          Y muestra una fecha repetida

          1572127200 :: 119.- 2019-10-27 0:00:00
          1572213600 :: 120.- 2019-10-27 23:00:00

          Lo curioso esta que cuando el rango es de 2019-01-01 al 2019-12-31
          Imprime bien los 365 Dias pero cuando acorto el rango como en el caso a partir de abril es decir 2019-04-01 al 2019-12-31. Este no muestra el ultimo día 2019-12-31 y repite el 2019-10-27, si le pongo las horas:minutos:Segundos, si muestra el ultimo día pero sigue repitiendo el 2019-10-27. A que se deberá?

          1. admin dice:

            Hola Juan Castillo,

            si, es muy extraño el problema que comentas. Yo acabo de hacer una prueba rapida con php 7.3 y no repite ese dia (ni ninguno) y muestra tambien el 2019-12-31.

            Creo que puede ser debido a la version de php, quizas estes con la 5.6 y sea algun tipo de bug extraño. Creo que a alguien mas le pasaba y me lo habia comentado tambien, pero fue hace tiempo y no me acuerdo como quedo la cosa.

            Si puedes, actualiza la version de php y compruébalo de nuevo, por lo menos en la 7.3 no pasa.

          2. Juan Castillo dice:

            Ya encontré el problema... el Problema es el Horario de Verano... como Cambia en Abril y Octubre.... cuando sumo el día... automaticamente agrega 1 hora en abril y luego la quita en Octubre es por ero que muestra Octubre 27 dos veces uno a las 00 y otro a las 23... no alcanza a brincar de dia...

            Esto lo solucione de la siguiente manera.

            $fecha_inicial = strtotime("2019-04-01 12:00:00");
            $fecha_final= strtotime("2019-12-31 12:00:00");

            Colocando el horario a medio día me funciona bien.

          3. admin dice:

            Hola Juan Castillo,

            me alegro que ya se haya resulto el problema. Curiosamente después de leer tu mensaje y revisando otros comentarios de la web, a otro usuario le pasaba lo mismo, y era justo por el tema del horario de verano, lo acabo de ver.

            Un saludo.

  4. yasmany dice:

    Hola soy nuevo y estaba buscando algo asi como el metod del rango de dos fechas.
    Lei tu metodo pero cuando capturo la fecha me devuelve los dias desde 1970 hasta la fecha final.en la parte de
    $fechaInicio=strtotime("25-02-2008");
    $fechaFin=strtotime"01-04-2008");
    ahi yo pongo
    $fechaInicio=strtotime($_post['fecha']);
    $fechaFin=strtotime($_post['fechaf']);
    por favor decirme si como lo estoy poniendo esta mal.
    muchas gracias

  5. issux dice:

    Gracias, INHack20. ;D

  6. Pekarnick dice:

    Muy bueno... como a 4 años de la publicación... muchas gracias!!

  7. Diogenes dice:

    Estimado como puedo saber el numero de meses dentro de un rango de fechas?. ayuda por favor.

  8. issux dice:

    Marielaf,

    Cambia la linea:

    echo date("d-m-Y", $i)."<br />";

    por

    echo date("m-Y", $i)."<br />";

    Saludos.

  9. INHack20 dice:

    Hermanooo justo lo que estaba buscando, funciona a la perfeccion, con el pude hacer otras cosas! Muchas Gracias!!

  10. Paco dice:

    Buen trabajo!! Muchas gracias!!!!

  11. marielaf dice:

    el codigo es muy bueno pero quiero hacer una consulta como hago para listar solo los meses y los años dentro del rango

  12. sony dice:

    muy buen aporte issux

  13. Lo he utilizado y funciona bien, rapido y sencillo como tiene que ser...gracias buen trabajo !!

  14. issux dice:

    Buenas.

    Es curioso, con php 5.3.3 no muestra ningun tipo de fecha repetida, muestra las fechas correctamente. Quizas sea algun bug de la version de php que estes utilizando (o quizas de la version y del ssoo).

    Saludos.

  15. yopi dice:

    hola soy nueva en todo esto mi problema es q necesito mostrar registros de la bd comprendidos en un rango de fechas, por ejemplo el usuario selecciona un periodo y debe obtener todos los registros comprendidos en ese periodo ordenados por fecha y en las q no hubo registros mostrarlo en blanco pero no tengo idea de como hacer esto espero me puedan ayudar. gracias

  16. Mario dice:

    Muy buen código, me estaba rompiendo la cabeza pensando en comparaciones extensas para rangos de fechas.. gracias por el aporte

  17. nick dice:

    cuando ejecuto
    $fechaInicio=strtotime("01-10-2009");
    $fechaFin=strtotime("23-12-2009");

    con esas fechas me repite la fecha:
    11/01/2009
    11/01/2009

    aparte no me muestra : 23-12-2009 que esta dentro del rango sin embargo si la muestra . Seria genial que no tiviera datalles, tambien me paso lo que a yasmany lo que le muestra desde la fecha 1970, me paso 2 veces extrañamanete estoy tratanto de replicar la falla

  18. issux dice:

    @ Ricardo G:

    La verdad es que ni había contemplado el uso de ficheros para guardar las fechas, me parece una solución poco eficiente. Como comentas, es mucho mejor guardarlas en la bd, nos permite mas flexibilidad.

    Y sobre recorrer fechas, el ejemplo esta pensado para un sistema de gestión de reservas, donde cada una tiene una fecha de inicio y otra de fin, pero evidentemente no duran años.

    Para casos como el tuyo donde el rango de fechas es de años, lo mejor es sacar la posición de las funciones strtotime fuera del bucle, ya que nos ahorramos una cantidad considerable de llamadas a dicha función, con lo que conseguimos mas rápidas y menos carga en el servidor.

    Por ejemplo, jugando un poco con el ab (100 consultas, con una concurrencia de 5 usuarios simultáneos) de apache vemos que:

    Ejemplo con strtotime dentro del for:
    Time taken for tests: 4.385 seconds
    Requests per second: 22.81 [#/sec] (mean)

    Ejemplo con strtotime fuera del bucle:

    Time taken for tests: 1.707 seconds
    Requests per second: 58.57 [#/sec] (mean)

    Las ventajas con el segundo método son evidentes.

    Gracias por el comentario, y saludos.

  19. Ricardo G dice:

    estimado, lo probe y no se demora mucho, menos de un segundo, en mi equipo, no lo he probado en un servidor.

    saludos !

  20. issux dice:

    Buenas.

    Si no he entendido mal, quieres saber el numero de dias entre dos fechas. Si es asi, es sencillo, prueba lo siguiente:

    $fechaInicio=strtotime($_post['fecha']);
    $fechaFin=strtotime($_post['fechaf']);
    $dias= (($fechaFin-$fechaInicio)/86400);

    Con esto sabras el numero de dias entre dos fechas.

    Saludos.

  21. Ricardo G dice:

    muy bueno, para fechas de no mas de un año, pero imagina si el rango de fecha es de 10 años son 365x10 uff ! un ciclo muy largo, y eso es cuando esas usando fechas guardadas en archivos, lo mejor seria directamente desde la base de datos, no crees ??

    saludos.

  22. Anonimus dice:

    Que relación tiene el numero 86400 con el correr de los días?

    1. issux dice:

      El numero de segundos de un día es 86400 ( 24h * 60m * 60sg = 86400 ).

  23. Fernando Muñoz dice:

    Gracias!
    Te haría click en algún Ad pero no encontré ninguno jaja

  24. Manel dice:

    cuidado con los días que se cambia la hora, funciona mal.

    1. Batman dice:

      que tiene que ver la hora con el rango entre dos fechas x

  25. Juan Liang dice:

    Excelente función. justo lo que necesitaba

Deja una respuesta

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

Subir