PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!
Moderator: General Moderators
Benjamin
Site Administrator
Posts: 6935 Joined: Sun May 19, 2002 10:24 pm
Post
by Benjamin » Tue Apr 11, 2006 6:50 pm
I haven't been able to find any accurate date difference examples so I am not sure where to start on this one. I need to accurately calculate the difference between 2 days, down to the hours minutes and seconds, while taking into account leap years. I wrote a function to do it but it's only accurate up to days because for months it assumes 30 days.
Code: Select all
function GetTimeDifference($StartTime, $Now) {
if (strtotime($StartTime) > $Now) {
$Seconds = strtotime($StartTime) - $Now;
} else {
$Seconds = $Now - strtotime($StartTime);
}
$Difference['Years'] = floor($Seconds / (365 * 24 * 60 * 60));
$Seconds = $Seconds - ($Difference['Years'] * (365 * 24 * 60 * 60));
$Difference['Months'] = floor($Seconds / (30 * 24 * 60 * 60));
$Seconds = $Seconds - ($Difference['Months'] * (30 * 24 * 60 * 60));
$Difference['Days'] = floor($Seconds / (24 * 60 * 60));
$Seconds = $Seconds - ($Difference['Days'] * (24 * 60 * 60));
$Difference['Hours'] = floor($Seconds / (60 * 60));
$Seconds = $Seconds - ($Difference['Hours'] * (60 * 60));
$Difference['Minutes'] = floor($Seconds / 60);
$Seconds = $Seconds - ($Difference['Minutes'] * 60);
$Difference['Seconds'] = ceil($Seconds);
return $Difference;
}
hawleyjr
BeerMod
Posts: 2170 Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA
Post
by hawleyjr » Tue Apr 11, 2006 6:57 pm
Code: Select all
/**
* Calculates the difference for two given dates, and returns the result
* in specified unit.
*
* @param string Initial date (format: [dd-mm-YYYY hh], hh is in 24hrs format)
* @param string Last date (format: [dd-mm-YYYY hh], hh is in 24hrs format)
* @param char 'd' to obtain results as days, 'h' for hours, 'm' for minutes, 's' for seconds, and 'a' to get an indexed array of days, hours, minutes, and seconds
*
* @return mixed The result in the unit specified (float for all cases, except when unit='a', in which case an indexed array), or null if it could not be obtained
*/
#http://us2.php.net/mktime
function getDateDifference($dateFrom, $dateTo, $unit = 'd')
{
$difference = null;
$dateFromElements = split(' ', $dateFrom);
$dateToElements = split(' ', $dateTo);
$dateFromDateElements = split('-', $dateFromElements[0]);
$dateFromTimeElements = split(':', $dateFromElements[1]);
$dateToDateElements = split('-', $dateToElements[0]);
$dateToTimeElements = split(':', $dateToElements[1]);
// Get unix timestamp for both dates
$date1 = mktime($dateFromTimeElements[0], $dateFromTimeElements[1], $dateFromTimeElements[2], $dateFromDateElements[1], $dateFromDateElements[0], $dateFromDateElements[2]);
$date2 = mktime($dateToTimeElements[0], $dateToTimeElements[1], $dateToTimeElements[2], $dateToDateElements[1], $dateToDateElements[0], $dateToDateElements[2]);
if( $date1 > $date2 )
{
return null;
}
$diff = $date2 - $date1;
$days = 0;
$hours = 0;
$minutes = 0;
$seconds = 0;
if ($diff % 86400 <= 0) // there are 86,400 seconds in a day
{
$days = $diff / 86400;
}
if($diff % 86400 > 0)
{
$rest = ($diff % 86400);
$days = ($diff - $rest) / 86400;
if( $rest % 3600 > 0 )
{
$rest1 = ($rest % 3600);
$hours = ($rest - $rest1) / 3600;
if( $rest1 % 60 > 0 )
{
$rest2 = ($rest1 % 60);
$minutes = ($rest1 - $rest2) / 60;
$seconds = $rest2;
}
else
{
$minutes = $rest1 / 60;
}
}
else
{
$hours = $rest / 3600;
}
}
switch($unit)
{
case 'd':
case 'D':
$partialDays = 0;
$partialDays += ($seconds / 86400);
$partialDays += ($minutes / 1440);
$partialDays += ($hours / 24);
$difference = $days + $partialDays;
break;
case 'h':
case 'H':
$partialHours = 0;
$partialHours += ($seconds / 3600);
$partialHours += ($minutes / 60);
$difference = $hours + ($days * 24) + $partialHours;
break;
case 'm':
case 'M':
$partialMinutes = 0;
$partialMinutes += ($seconds / 60);
$difference = $minutes + ($days * 1440) + ($hours * 60) + $partialMinutes;
break;
case 's':
case 'S':
$difference = $seconds + ($days * 86400) + ($hours * 3600) + ($minutes * 60);
break;
case 'a':
case 'A':
$difference = array (
"days" => $days,
"hours" => $hours,
"minutes" => $minutes,
"seconds" => $seconds
);
break;
}
return $difference;
}
hawleyjr
BeerMod
Posts: 2170 Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA
Post
by hawleyjr » Tue Apr 11, 2006 6:59 pm
Also, Don't forget to check out the mysql date functions : DATEDIFF(expr,expr2)
Benjamin
Site Administrator
Posts: 6935 Joined: Sun May 19, 2002 10:24 pm
Post
by Benjamin » Tue Apr 11, 2006 7:18 pm
Thank you, I appreciate that, but that is still calculating the difference based on seconds. When it's done that way, don't you lose the ability to calculate months & years precisely,? because of leap years?
timvw
DevNet Master
Posts: 4897 Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium
Post
by timvw » Tue Apr 11, 2006 7:44 pm
agtlewis wrote: Thank you, I appreciate that, but that is still calculating the difference based on seconds. When it's done that way, don't you lose the ability to calculate months & years precisely,? because of leap years?
Who said you can't take leap years into account?