Search code examples
phplaravelphp-carbontinker

Weird results for Nesbot Carbon diffInHours


I was doing some tinkering for another question here on SO. And have some weird behavior for Carbon's diffInHours. The diff of time ahead is not the same as the diff of time past. Here is my tinker commands and return values:

>>> \Carbon\Carbon::now()->diffInHours(\Carbon\Carbon::now()->addHours(3))
=> 3
>>> \Carbon\Carbon::now()->addHours(3)->diffInHours(\Carbon\Carbon::now())
=> 2
>>> \Carbon\Carbon::now()->addHours(3)->diffInHours(\Carbon\Carbon::now())
=> 2
>>> \Carbon\Carbon::now()->addHours(3)->diffInHours(\Carbon\Carbon::now())
=> 2
>>> \Carbon\Carbon::now()
=> Carbon\Carbon @1595427497 {#4431
     date: 2020-07-22 14:18:17.952594 UTC (+00:00),
   }

Does anyone have any insight as to what is causing this behavior?


Solution

  • \Carbon\Carbon::now()->addHours(3)->diffInHours(\Carbon\Carbon::now();
    

    let us break it down to figure out what is going on:

    1- you get the datetime that represent now.

    2- you add 3 hours to it. result will be now + 3 hour.

    3- you get diffInHours with 'now'(witch is different from first 'now' after it by few parts of a second) witch would be 2.9999999180556

    4- the diffInHours round the result down (as in doc), the result will be 2 ..

    if you want to get the real diff without rounding, you can use floatDiffInRealHours, that will give you 2.9999999180556

    The issue is the delay between the two \Carbon\Carbon::now() being called. You can see there is no issue, if you use a copied Carbon instance:

    >>> $now = \Carbon\Carbon::now()
    => Carbon\Carbon @1595429110 {#4367
         date: 2020-07-22 14:45:10.767156 UTC (+00:00),
       }
    >>> $threeHoursFromNow = $now->copy()->addHours(3)
    => Carbon\Carbon @1595439910 {#4428
         date: 2020-07-22 17:45:10.767156 UTC (+00:00),
       }
    >>> $now->diffInHours($threeHoursFromNow)
    => 3
    >>> $threeHoursFromNow->diffInHours($now)
    => 3