I'm working on the application where I want to calculate the total late hours of an employee from a set of records between the employee timing shift?

Example Of Employee Time Shift

Shift Start: 01:00:00
Shift End:   09:00:00

Php Code

// example 1
error_reporting('0');
$time1 = "01:00:00";
$time2 = "09:00:00";

date_default_timezone_set('Asia/Karachi');

echo "Time difference: ".get_time_difference($time1, $time2)." hours<br/>";

function get_time_difference($time1, $time2)
{
    $date = date('h:i:s a', time());
    $time1 = strtotime("1/1/1980 $time1");
    $time2 = strtotime("1/1/1980 $time2");
    $totalshifttime = ($time2 -$time1) / 3600;
    $totallate= $totalshifttime - $date ;

return $totallate;

}?

Let's support if ABC employee clock in at 2 pm then should automatically display 1 hour late current function is showing 7 hours late?

Dani AI

Generated

The root cause is subtracting the wrong values and using formatted strings instead of timestamps. As explained, lateness is simply max(0, clock_in_time - shift_start_time). ’s function ended up subtracting the wrong quantities and mixing formatted output with numeric math, which produced the wrong result. The clean approach is: parse times into real DateTime/timestamps (same base date), compute the difference in seconds, then convert to hours.

PHP — compact, robust example (handles same-day and simple next-day cases)

<?php
function hours_late(string $shiftStart, string $clockIn, string $tz = 'UTC'): float {
    $tzObj = new DateTimeZone($tz);
    $base = (new DateTime('today', $tzObj))->format('Y-m-d');
    $s = DateTime::createFromFormat('Y-m-d H:i:s', $base . ' ' . $shiftStart, $tzObj);
    $c = DateTime::createFromFormat('Y-m-d H:i:s', $base . ' ' . $clockIn, $tzObj);
    if (!$s || !$c) return 0.0;
    if ($c < $s && ($s->getTimestamp() - $c->getTimestamp()) > 12*3600) {
        $c->modify('+1 day'); // simple next-day adjustment for overnight shifts/punches
    }
    $sec = $c->getTimestamp() - $s->getTimestamp();
    return max(0.0, round($sec / 3600, 2));
}

echo hours_late('13:00:00', '14:00:00', 'Asia/Karachi'); // 1.00

Python — equivalent logic

from datetime import datetime, date, timedelta

def hours_late(shift_start: str, clock_in: str) -> float:
    today = date.today()
    s = datetime.combine(today, datetime.strptime(shift_start, '%H:%M:%S').time())
    c = datetime.combine(today, datetime.strptime(clock_in, '%H:%M:%S').time())
    if c < s and (s - c) > timedelta(hours=12):
        c += timedelta(days=1)
    seconds = (c - s).total_seconds()
    return max(0.0, round(seconds / 3600.0, 2))

print(hours_late('13:00:00', '14:00:00'))  # 1.0

Notes and gotchas: always work with full datetimes (avoid subtracting formatted strings), store timestamps in UTC when possible, sum raw seconds when aggregating multiple records, and decide clear business rules for overnight shifts (shift start > shift end) — ambiguous time-only data requires a rule for day assignment.

Your problem is in line 15 and 16:

  15.  $totalshifttime = ($time2 -$time1) / 3600;
  16.  $totallate= $totalshifttime - $date ;

15 subtracts $time1 from $time2 / 3600 (hrs): 09:00-01:00 = 08:00/3600 = 8.
16 subtracts current time (say 02:00) from 8, not even 8:00 ????

I think what you want is the current time minus time1: ($date - $time1)/3600. if >0 the hours late.

The shift end is never used in deciding if the person was late for shift start. If you want to see hours not worked, you want (shift end - shift start) - (person end - person start). if > 0, the hours and minutes not worked.

HTH,
Sean

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.