phpdatetimefloating-pointdayscalc

DateInterval total number of days as float


For now I don't care about timezones and just want to have a correct calculated value of how many days are between two dates. I think I'm pretty near to what I want, but for me there is always a full day missing.

That's what I got so far:

$start = new DateTimeImmutable('2018-07-31 12:30:00');
$end = new DateTimeImmutable('2018-08-28 00:00:00');
$diff = $start->diff($end);

$totalDays = (int) $diff->days; // 27
$hours = $diff->h;              // 11
$minutes = $diff->i;            // 30
$seconds = $diff->s;            //  0

$hoursAsDays = $hours / 24;               // 0.45833333333333
$minutesAsDays = $minutes / 60 / 24;      // 0.020833333333333
$secondsAsDays = $seconds / 60 / 60 / 24; // 0
$result = $totalDays + $hoursAsDays + $minutesAsDays + $secondsAsDays;

var_dump($result); // 27.479166666667

For me there are 28 full days from august. I thought I would get something like: 28.45

EDIT: Users who add '2018-08-28' as end date will assume that it will count as a full day. How do I safely make this possible to be mentioned in my calculation?


Solution

  • You can do that simply with strtotime() PHP function:

    $start = '2018-07-31 12:30:00';
    $end = '2018-08-28 00:00:01';
    
    echo $diffDays = (strtotime($end) - strtotime($start)) / 60 / 60 / 24;
    

    Result:

    27.479166666667
    

    The result is true because there are exactly 27,5 days (in terms of 24 hours per day) between the two dateTime:

    27 days and early a half day:
    from 2018-07-31 12:30 to 2018-07-31 23.59 = +1/2 day tot:    0,5
    from 2018-08-01 00:00 to 2018-08-01 23.59 = +1 day   tot:    1,5
    from 2018-08-02 00:00 to 2018-08-01 23.59 = +1 day   tot:    2,5
    from 2018-08-03 00:00 to 2018-08-01 23.59 = +1 day   tot:    3,5
    from 2018-08-04 00:00 to 2018-08-01 23.59 = +1 day   tot:    4,5
    from 2018-08-05 00:00 to 2018-08-01 23.59 = +1 day   tot:    5,5
    from 2018-08-06 00:00 to 2018-08-01 23.59 = +1 day   tot:    6,5
    from 2018-08-07 00:00 to 2018-08-01 23.59 = +1 day   tot:    7,5
    from 2018-08-08 00:00 to 2018-08-01 23.59 = +1 day   tot:    8,5
    from 2018-08-09 00:00 to 2018-08-01 23.59 = +1 day   tot:    9,5
    from 2018-08-10 00:00 to 2018-08-01 23.59 = +1 day   tot:   10,5
    from 2018-08-11 00:00 to 2018-08-01 23.59 = +1 day   tot:   11,5
    from 2018-08-12 00:00 to 2018-08-01 23.59 = +1 day   tot:   12,5
    from 2018-08-13 00:00 to 2018-08-01 23.59 = +1 day   tot:   13,5
    from 2018-08-14 00:00 to 2018-08-01 23.59 = +1 day   tot:   14,5
    from 2018-08-15 00:00 to 2018-08-01 23.59 = +1 day   tot:   15,5
    from 2018-08-16 00:00 to 2018-08-01 23.59 = +1 day   tot:   16,5
    from 2018-08-17 00:00 to 2018-08-01 23.59 = +1 day   tot:   17,5
    from 2018-08-18 00:00 to 2018-08-01 23.59 = +1 day   tot:   18,5
    from 2018-08-19 00:00 to 2018-08-01 23.59 = +1 day   tot:   19,5
    from 2018-08-20 00:00 to 2018-08-01 23.59 = +1 day   tot:   20,5
    from 2018-08-21 00:00 to 2018-08-01 23.59 = +1 day   tot:   21,5
    from 2018-08-22 00:00 to 2018-08-01 23.59 = +1 day   tot:   22,5
    from 2018-08-23 00:00 to 2018-08-01 23.59 = +1 day   tot:   23,5
    from 2018-08-24 00:00 to 2018-08-01 23.59 = +1 day   tot:   24,5
    from 2018-08-25 00:00 to 2018-08-01 23.59 = +1 day   tot:   25,5
    from 2018-08-26 00:00 to 2018-08-01 23.59 = +1 day   tot:   26,5
    from 2018-08-27 00:00 to 2018-08-01 23.59 = +1 day   tot:   27,5
    from 2018-08-28 00:00 to 2018-08-28 00:00 = +0 day   tot:   27,5
    

    With strtotime() you can convert a date/datetime string into instant version (count from epoch in seconds).

    Regarding your edit, to consider the ending day in the calculation, set its time as 23:59:59:

    $end = date('Y-m-d 23:59:59', strtotime('2018-08-28 00:00:01'));
    

    Thus, the result will be:

    28.479155092593