Obtenga una diferencia de fecha y hora de PHP en días, considerando la medianoche como un cambio de día


¿Cuál es la forma más sencilla de obtener la diferencia en días entre dos PHP DateTimes, considerando la medianoche como un cambio de día (al igual que lo hace la función SQL DATEDIFF(DAY))?

Por ejemplo, entre hoy a las 13:00 y mañana a las 12:00, debería obtener 1 (día), aunque el intervalo sea inferior a 24 horas.

$date1 = new DateTime("2013-08-07 13:00:00");
$date2 = new DateTime("2013-08-08 12:00:00");
echo $date1->diff($date2)->days; // 0
Author: marcv, 2013-08-07

4 answers

Podría ignorar la parte de tiempo de la cadena de fecha

$date1 = new DateTime(date('Y-m-d', strtotime("2013-08-07 13:00:00")));
$date2 = new DateTime(date('Y-m-d', strtotime("2013-08-08 12:00:00")));
echo $date1->diff($date2)->days; // 0
 37
Author: MajorCaiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 11:53:05

Una solución simple a esto para quitar el tiempo o establecerlo en 00:00:00, que siempre debe darle el resultado deseado:

$date1 = new DateTime("2013-08-07");
$date2 = new DateTime("2013-08-08");
echo $date1->diff($date2)->days;

O

$date1 = new DateTime("2013-08-07 00:00:00");
$date2 = new DateTime("2013-08-08 00:00:00");
echo $date1->diff($date2)->days;

El tiempo realmente no importa aquí

 6
Author: x4rf41,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 11:51:09

Tenga en cuenta que DateInterval->days siempre es positivo. de ahí el uso de - > invertir.

/**
 * return amount of days between dt1 and dt2 
 * (how many midnights pass going from dt1 to dt2)
 *  0 = same day, 
 * -1 = dt2 is 1 day before dt1, 
 *  1 = dt2 is 1 day after  dt1, etc.
 *
 * @param \DateTime $dt1
 * @param \DateTime $dt2
 * @return int|false 
 */
function getNightsBetween(\DateTime $dt1, \DateTime $dt2){
    if(!$dt1 || !$dt2){
        return false;
    }
    $dt1->setTime(0,0,0);
    $dt2->setTime(0,0,0);
    $dti = $dt1->diff($dt2);    // DateInterval
    return $dti->days * ( $dti->invert ? -1 : 1);   // nb: ->days always positive
}

Ejemplos de uso:

$dt1 = \DateTime::createFromFormat('Y-m-d', '2014-03-03' );
$dt2 = \DateTime::createFromFormat('Y-m-d', '2014-02-20' );
getNightsBetween($dt1, $dt2);       // -11

$dt1 = \DateTime::createFromFormat('Y-m-d H:i:s', '2014-01-01 23:59:59' );
$dt2 = \DateTime::createFromFormat('Y-m-d H:i:s', '2014-01-02 00:00:01' );
getNightsBetween($dt1, $dt2);       // 1 (only 2 seconds later, but still the next day)

$dt1 = \DateTime::createFromFormat('Y-m-d', '2014-04-09' );
$dt2 = new \DateTime();
getNightsBetween($dt1, $dt2);       // xx (how many days (midnights) passed since I wrote this)

Ejemplo de alguna magia de texto:

function getRelativeDay(\DateTime $dt2){
    if(!$dt2){
        return false;
    }
    $n = getNightsBetween( new \DateTime(), $dt2);
    switch($n){
        case  0: return "today";
        case  1: return "tomorrow";
        case -1: return "yesterday";
        default: 
            return $n . (abs($n)>1?"days":"day") . ($n<0?" ago":" from now");
    }
}
 6
Author: MoonLite,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-01 11:34:05

Este ejemplo puede ayudarte:

   $date1 = date_create($d1);
$date2 = date_create($d2);
//$FromFullDateTime=$from.$FromTime;

$date1_month = date_format($date1, 'd');
$date2_month = date_format($date2, 'd');
$dif = $date2_month - $date1_month;
 -2
Author: Samira Khorshidi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 12:41:15