Nick
Nick

Reputation: 3965

PHP - hours difference (HH:MM format)

I'm trying to calculate the shift patterns of people who work here, subtracting the start time from the end time works for the most part, but not if they're working overnight. For example someone working from 10pm to 6am would be displayed as:

22:00 - 06:00

I'd like that to return 8 hours, but I just can't figure out the best way of doing it.

Annoyingly, I'm then going to have to do the exact same thing in Javascript, so I hope I can get my head around the logic for this. Taking away one date from the other just doesn't work in this case...

Any help would be much appreciated, thank you!

Upvotes: 4

Views: 13703

Answers (6)

AO_
AO_

Reputation: 2874

function timeDiff($firstTime,$lastTime) {
    $firstTime=strtotime($firstTime);
    $lastTime=strtotime($lastTime);
    $timeDiff=$lastTime-$firstTime;
    return $timeDiff;
}

echo (timeDiff("10:00","12:00")/60)/60;

Originally wrote this here: https://ataiva.com/how-to-get-the-hours-difference-in-hhmm-format-in-php/

Upvotes: 8

Jon
Jon

Reputation: 437376

Old school, with string manipulation and math:

$input = '22:00 - 06:00';
preg_match('/(\d+):(\d+)\D*(\d+):(\d+)/', $input, $matches);
list(, $startHour, $startMin, $endHour, $endMin) = $matches;
$totalMinutes = ($endHour * 60 + $endMin - $startHour * 60 + $startMin + 1440) % 1440;
$hours = floor($totalMinutes / 60);
$mins = $totalMinutes % 60;

echo "works for $hours hours, $mins minutes";

With date/time functions:

$input = '22:00 - 06:00';
list($start, $end) = array_map('trim', explode('-', $input));
$start = new DateTime($start.'+00:00');
$end = new DateTime($end.'+00:00');
if ($start > $end) $start->sub(new DateInterval('P1D'));
$interval = $end->diff($start);
echo "works for ".$interval->h." hours, ".$interval->m." minutes";

Devilish gotcha for any solution using date/time functions:

If you do not explicitly specify the offset for $start and $end, and we are talking about a night shift, and the code is run on the day where daylight savings time starts or ends the results would be off by whatever the DST offset is.

This is true for any solution that uses DateTime, strtotime, etc.

Upvotes: 5

Nauber
Nauber

Reputation: 21

You can use the function mktime (http://php.net/manual/en/function.mktime.php) to return the number of seconds and subtract the two dates in integer format.

<?php
   $date1=mktime(1, 2, 3, 4, 5, 2006);
   $date2=mktime(1, 2, 3, 4, 5, 2008);
   $diference=$date2-$date1;

   echo $diference

   ?>

Upvotes: 2

adrien
adrien

Reputation: 4439

Working AND most easy sample :

$start = 22;
$end = 6;

if ($start > $end) {
    $end += 24;
}

$duration = $end - $start;

echo 'Duration: ' . $duration . 'hours.';

Upvotes: 1

silly
silly

Reputation: 7887

without some date function:

$start = '22:00';
$end = '06:00';

$getnum = function($value) {
    $pieces = explode(':', $value);
    if(count($pieces) > 0) {
        return (intval($pieces[0])*60)+intval($pieces[1]);
    }

    return 0;
};

$start_num = $getnum->__invoke($start);
$end_num = $getnum->__invoke($end);

$diff = max($start_num, $end_num) - min($end_num, $start_num);

echo intval($diff / 60).'.'.($diff % 60).' hours';

Upvotes: 3

Logan Serman
Logan Serman

Reputation: 29870

You can look into date_diff, which is an alias of this function:

http://www.php.net/manual/en/datetime.diff.php

MySQL also has a DATEDIFF() function, so if you are grabbing them from a database you can do it directly from SQL (I know you didn't specify, but I just wanted to mention this).

Upvotes: -1

Related Questions