You want to find the difference of two dates measured by what a clock would say, not the actual elapsed time.
Use gregoriantojd( ) to get the Julian day for a set of date parts, then subtract one Julian day from the other to find the date difference. Then convert the time parts to seconds and subtract one from the other to find the time difference. If the time difference is less than 0, decrease the date difference by one and adjust the time difference to apply to the previous day. Here's the code:
$diff_date = gregoriantojd($date_1_mo, $date_1_dy, $date_1_yr) - gregoriantojd($date_2_mo, $date_2_dy, $date_2_yr); $diff_time = $date_1_hr * 3600 + $date_1_mn * 60 + $date_1_sc - $date_2_hr * 3600 - $date_2_mn * 60 - $date_2_sc; if ($diff_time < 0) { $diff_date--; $diff_time = 86400 - $diff_time; }
Finding differences with Julian days lets you operate outside the range of epoch seconds and also accounts for DST differences.
If you have the components of your two days in arrays:
// 7:32:56 pm on May 10, 1965 list($date_1_yr, $date_1_mo, $date_1_dy, $date_1_hr, $date_1_mn, $date_1_sc)= array(1965, 5, 10, 19, 32, 56); // 4:29:11 am on November 20, 1962 list($date_2_yr, $date_2_mo, $date_2_dy, $date_2_hr, $date_2_mn, $date_2_sc)= array(1962, 11, 20, 4, 29, 11); $diff_date = gregoriantojd($date_1_mo, $date_1_dy, $date_1_yr) - gregoriantojd($date_2_mo, $date_2_dy, $date_2_yr); $diff_time = $date_1_hr * 3600 + $date_1_mn * 60 + $date_1_sc - $date_2_hr * 3600 - $date_2_mn * 60 - $date_2_sc; if ($diff_time < 0) { $diff_date--; $diff_time = 86400 - $diff_time; } $diff_weeks = floor($diff_date/7); $diff_date -= $diff_weeks * 7; $diff_hours = floor($diff_time/3600); $diff_time -= $diff_hours * 3600; $diff_minutes = floor($diff_time/60); $diff_time -= $diff_minutes * 60; print "The two dates have $diff_weeks weeks, $diff_date days, "; print "$diff_hours hours, $diff_minutes minutes, and $diff_time "; print "seconds between them."; The two dates have 128 weeks, 6 days, 15 hours, 3 minutes, and 45 seconds between them.
This method produces a time difference based on clock time, which is why the result shows an hour more of difference than in Recipe 3.6. May 10 is during DST, and November 11 is during standard time.
The function gregoriantojd( ) is part of PHP's calendar extension, and so is available only if that extension is loaded.
Recipe 3.6 to find the difference between two dates in elapsed time; Recipe 3.11 for adding and subtracting from a date; documentation on gregoriantojd( ) at http://www.php.net/gregoriantojd; an overview of the Julian Day system is at http://tycho.usno.navy.mil/mjd.html.
Copyright © 2003 O'Reilly & Associates. All rights reserved.