96

I'm trying to figure out how I can take two date time strings that are stored in our database and convert it to a difference in time format of hh:mm:ss.

I looked at diffForHumans, but that does give the format I'd like and returns things like after, ago, etc; which is useful, but not for what I'm trying to do.

The duration will never span days, only a max of a couple hours.

$startTime = Carbon::parse($this->start_time);
$finishTime = Carbon::parse($this->finish_time);

$totalDuration = $finishTime->diffForHumans($startTime);
dd($totalDuration);

// Have: "21 seconds after"
// Want: 00:00:21
mtpultz
  • 17,267
  • 22
  • 122
  • 201
  • 2
    fyi, `$totalDuration = $finishTime->diffForHumans($startTime, true); dd($totalDuration);` Should return "21 seconds". I know that still isn't the format you were looking for, but that is how you remove things like "after" and "ago", as referenced in your question. – willjohnathan Jul 16 '17 at 21:40

5 Answers5

132

I ended up grabbing the total seconds difference using Carbon:

$totalDuration = $finishTime->diffInSeconds($startTime);
// 21

Then used gmdate:

gmdate('H:i:s', $totalDuration);
// 00:00:21

If anyone has a better way I'd be interested. Otherwise this works.

mtpultz
  • 17,267
  • 22
  • 122
  • 201
  • 43
    Only other way I can think of is `$finishTime->diff($startTime)->format('%H:%i:%s');` – Thomas Kim Nov 06 '15 at 22:44
  • 5
    None of these work, if the dates have different days (e.g. Jan 1st and Jan 5th). – Alex Jan 18 '17 at 21:44
  • I've tested this solution spanning dates (different days) and it works. Thanks mtpultz. – mcmacerson Nov 18 '17 at 00:22
  • 2
    Only works if diffInSeconds < 86400 (24 hours). Use `floor($totalDuration / 3600) . gmdate(":i:s", $totalDuration % 3600)` to get durations > 24 hours, e.g. 72:16:12 (72 hours, 16 minutes, 12 seconds). – M165437 Dec 01 '17 at 20:16
  • @Alex see my answer for a solution that works for different days – Adam Apr 24 '19 at 08:07
58
$finishTime->diff($startTime)->format('%H:%I:%S');
// 00:00:21
STWilson
  • 1,538
  • 2
  • 16
  • 26
58
$start  = new Carbon('2018-10-04 15:00:03');
$end    = new Carbon('2018-10-05 17:00:09');

You may use

$start->diff($end)->format('%H:%I:%S');

which gives the difference modulo 24h

02:00:06

If you want to have the difference with more than 24h, you may use :

$start->diffInHours($end) . ':' . $start->diff($end)->format('%I:%S');

which gives :

26:00:06

Ousmane
  • 2,673
  • 3
  • 30
  • 37
Adam
  • 25,960
  • 22
  • 158
  • 247
5

I know this is an old question, but it still tops Google results when searching for this sort of thing and Carbon has added a lot of flexibility on this, so wanted to drop a 2022 solution here as well.

TL;DR - check out the documentation for different/more verbose versions of the diffForHumans method, and greater control over options.

As an example, we needed to show the difference between two Carbon instances (start and end) in hours & minutes, but it's possible they're more than 24 hours apart—in which case the minutes become less valuable/important. We want to exclude the "ago" or Also wanted to join the strings with a comma.

We can accomplish all of that, with the $options passed into diffForHumans, like this:

use Carbon\CarbonInterface;

$options = [
  'join' => ', ',
  'parts' => 2,
  'syntax' => CarbonInterface::DIFF_ABSOLUTE,
];

return $end->diffForHumans($start, $options);

Which will result in values like what's seen in the Duration column:

Hope that's helpful for someone!

cdwyer
  • 589
  • 6
  • 22
3

You can do it using the Carbon package this way to get the time difference:

$start_time = new Carbon('14:53:00');
$end_time = new Carbon('15:00:00');
$time_difference_in_minutes = $end_time->diffInMinutes($start_time);//you also find difference in hours using diffInHours()
Simon Angatia
  • 688
  • 1
  • 10
  • 16