Código PHP

Recorrer un rango de fechas en php

Recorrer un rango de fechas en php
5 (100%) 2 voto[s]

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

51 comentarios en “Recorrer un rango de fechas en php”

  1. Como puedo implementar un buscador por fechas y por palabras, pero que busque en la misma lista que me encuentro y que no me busque en general.

    1. Hola Luki,

      el implementar un buscador y que funcione correctamente como dices (buscando por fechas y palabras no es sencillo). No se realmente si lo buscas en php o en otro lenguaje y si usas un cms o no, ya que dependiendo de ambas cosas, cambiaria.

      Si usas un cms tipo wordpress o similar, te recomendaria que buscases algun plugin. Hay plugins que amplian el buscador por defecto, e incluso realizan la busqueda por campos personalizados.

      Siento no poder ayudarte mas, pero con tan poco datos es dificil.

      Saludos.

      1. Te cuento que lo estoy haciendo con puro PHP, lo malo es que cuando ejecuto la busqueda lo hace en general y no con la lista que sale al momento de ingresar a los clientes

        1. digamos que como usuario yo agregue a 10 clientes y cuando ingrese a mi lista de clientes pueda buscar en especifico a esos 10 clientes, hasta ahí lo tengo echo pero resulta que cuando hago buscar lo hace en general y busca los clientes de los demás usuarios, mi código de la lista esta programado con PHP y para la base de datos wampServe – phpmyadmin

          1. Hola Luki,
            tal y como lo he entendido, lo que haria es en el codigo del buscador comprobar si hay un usuario logueado (si esta logueado, tendras su id guardada en sesion). Entonces, modificar la consulta del buscador para que limite la busqueda de cliente solo a los asociados a ese usuario logueado. Algo asi:

            $consulta = mysql_query(‘SELECT * FROM clients WHERE user_owner = ‘.$_SESSION[‘user_id’]);

            En la tabla de clientes tendras un campo asociado indicando que usuario de los que hacen login lo ha dado de alta (user_owner) y user_id es la variable de sesion que guarda el id del usuario que ha hecho login.

            Modificando la consulta del buscador, te deberia funcionar.

      2. your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘0, 50’ at line 2
        ahora me sale ese error

        $query = mysqli_query($conection,»SELECT * FROM cliente WHERE
        ( user_owner = ‘».$_SESSION[‘idUser’].»‘ $desde, $por_pagina») or die(mysqli_error($conection));

        1. Hola Luki,

          creo que el error que te da es por que le falta el limit(te lo marco en negrita) en la consulta:
          $query = mysqli_query($conection,»SELECT * FROM cliente WHERE
          ( user_owner = ‘».$_SESSION[‘idUser’].»‘ LIMIT $desde, $por_pagina») or die(mysqli_error($conection));

          Saludos.

  2. yo ocupo.. que al momento de presionar un botón que diga 4 meses.. todas las personas que se registraron hace 4 meses aparezcan.. tendría que comparar la fecha actual y en automático la de hace 4 meses.. osea que se agrupen los registros… Como lo hago???? en PHP

  3. Cómo puedo hacer para recorrer varios rangos al mismo tiempo?

    Osea voy a extraerlos de una dB, pero las fecha van a estar saltando.

  4. Tengo algo similar pero no tiene el problema del día final

    <?php

    $fechaInicio = "2014-02-01";

    $fechaFin = "2014-03-31";

    for($i=$fechaInicio; $i<=$fechaFin; $i = date("Y-m-d", strtotime($i ."+ 1 days"))){

    echo date("d-m-Y", strtotime($i)) . "»;

    }

    ?>

  5. Hola issux gracias por responder, fíjate he cambiado los tipos de datos he hecho de todo pero no me funciona, no tengo mucha experiencia con el manejo de fechas y menos desde datepicker, necesito un poco más de ayuda a nivel de código. Gracias de antemano

  6. Hola Issux estoy haciendo un sistema de reservas y quiero comparar dos rangos de fechas, una fecha_inicio y una fecha_fin para que cuando un rango de fechas reservadas le indique al cliente que ya están reservadas, ejemplo: si ya hay una reserva hecha desde el 12/06/2013 al 25/06/2013 que en ese rango de fechas no pueda reservar y el sistema le indique que están ocupadas he intendado de varias maneras y no he podido:

    acá te dejo algo de lo que hecho a ver en que puedes ayudarme, gracias de antemano.

    $sql=(«SELECT * FROM reservacion_departamento WHERE fecha_inicio, fecha_fin BETWEEN ‘dd/mm/aa’ AND ‘dd/mm/aa’;»);
    $consulta=mysql_query($sql,$conexion);
    while($resultado=mysql_fetch_array($consulta)){
    if (($fecha_inicio) <= ($resultado[&#039fecha_inicio&#039]))
    $flag = 1;
    else
    $flag = 0;
    }
    if ($flag == 1){
    echo ("
    alert (‘fecha no disponible…’)
    «);
    }
    else
    {
    echo (»
    alert (‘Fechas disponibles, reserve ahora…’)
    location.href = ‘reserva_departamento.php’;
    «);
    }
    }//Fin consultar

    1. Hola Andrés,

      El problema tiene toda la pinta de ser por el tipo de dato de la bd, que supongo que debe ser un date y las comparaciones que se hacen. Cambiaría el tipo de dato de la tabla por un timestamp, y de esta manera las comparaciones no me darían problemas. Puedes utilizar el método strtotime() para convertir a timestamp la fecha, y revisa la pagina http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html para las funciones de conversión de fechas de mysql.

      Saludos.

  7. Isaac Rosario Duran

    Alguien sabe como hacer eso mismo en Javascript. Estoy implementando un calendario de disponibilidad, el cual paso las fechas a un script de JS y el formato de fecha es el siguiente [‘2017-03-02’] osea Y-m-d pero cuando le paso estos datos el calendario solo me muestra la ultima fecha en rojo, y omite las demas.

    pero si hago un echo con php me sale lo que quiero, pero no he podido combinarlos con JS.
    Alguien puede ayudarme por favor, mis conocimientos de JS son muy muy básicos.

  8. Sarai Santiago Sanchez

    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. 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

  9. LUIS PUMARICRA DIAZ

    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. 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. también se arregla con esto :

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

  10. 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

  11. 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.

  12. 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

  13. 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

  14. @ 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.

  15. 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.

  16. muy bueno, para fechas de no mas de un año, pero imagina si el rango de fecha es de 10 años son 365×10 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.

Dejar un comentario

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