note 77281 deleted from ref.datetime by felipe
| From: | felipe@php.net | Date: | Mon, 10 Dec 2007 17:50:28 +0000 |
| Subject: | note 77281 deleted from ref.datetime by felipe | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-133215@lists.php.net to get a copy of this message | ||
Note Submitter: carsten dot klein at abstraxion dot org
----
This will calculate the duration between two arbitrary dates that are valid within the given unix
timestamp range. It also takes care of leap years, that is, if the minimum date is a leap year and
the beginning month is February it will take into account the leap days, if any.
The below routine assumes that you a DateTime object that supports the following methods:
getYear(), getMonth(), getDayOfMonth(), getHourOfDay(), getMinuteOfHour(), and getSecondOfMinute()
Adapt as you wish.
---8<--- snip --->8---
$min = DateTime::fromString( "1980-02-01 01:01:00" );
$max = DateTime::fromString( "2004-01-02 14:10:00" );
echo "min: " . $min . "<br>";
echo "max: " . $max . "<br>";
$rtmcorr = 0; // TM correction
$rthcorr = 0; // TH correction
$rdcorr = 0; // D correction
$rmcorr = 0; // M correction
$rycorr = 0; // Y correction
$my = $max->getYear();
$mm = $max->getMonth();
$md = $max->getDayOfMonth();
$mth = $max->getHourOfDay();
$mtm = $max->getMinuteOfHour();
$mts = $max->getSecondOfMinute();
$ny = $min->getYear();
$nm = $min->getMonth();
$nd = $min->getDayOfMonth();
$nth = $min->getHourOfDay();
$ntm = $min->getMinuteOfHour();
$nts = $min->getSecondOfMinute();
$ry = 0;
$rm = 0;
$rd = 0;
$rth = 0;
$rtm = 0;
$rts = 0;
// rts
if ( $my == $ny && $mm == $nm && $md == $nd && $mth == $nth && $mtm
== $ntm )
{
$rts = $mts - $nts;
}
else
{
$rts = 60 - ( $nts == 0 ? 60 : $nts ) + $mts;
$rtmcorr = $rts == 0 ? 0 : ( $rts > 60 ? 1 : -1 );
$rts = $rts % 60;
}
echo "rts: " . $rts . "<br>";
echo "rtmcorr: " . $rtmcorr . "<br>";
// rtm
if ( $my == $ny && $mm == $nm && $md == $nd && $mth == $nth )
{
$rtm = $mtm - $ntm + $rtmcorr;
}
else
{
$rtm = 60 - ( $ntm == 0 ? 60 : $ntm ) + $mtm;
$rtmcorr = $rtm == 0 ? 0 : ( $rtm > 60 ? 1 : -1 );
$rtm = $rtm % 60;
}
echo "rtm: " . $rtm . "<br>";
echo "rthcorr: " . $rthcorr . "<br>";
// rth
if ( $my == $ny && $mm == $nm && $md == $nd )
{
$rth = $mth - $nth + $rthcorr;
}
else
{
$rth = 24 - ( $nth == 0 ? 24 : $nth ) + ( $md - $nd ) * 24 + $mth + $rthcorr;
$rdcorr = $rth == 0 || $rth > 24 ? 0 : -1; //( $rth > 24 ? 0 : -1 );
$rth = $rth % 24;
}
echo "rth: " . $rth . "<br>";
echo "rdcorr: " . $rdcorr . "<br>";
$isLeapYear = ( $ny % 4 == 0 || $ny % 100 == 0 ) && ! ( $ny % 400 == 0 );
$daysInMonthCorrection = $nm == 2 ? ( $isLeapYear ? -1 : -2 ) : ( $nm == 8 ? 1 : ( $nm % 2 == 0 ? 0
: 1 ) );
$daysInMonth = 30 + $daysInMonthCorrection;
echo "daysInMonth: " . $daysInMonth . "<br>";
echo "daysInMonthCorrection: " . $daysInMonthCorrection . "<br>";
$doff = 0;
$mcorr = 0;
if ( $my == $ny && $mm == $nm )
{
$rd = $md - $nd + $rdcorr;
}
else
{
$rd = $daysInMonth - ( $nd == 1 ? $daysInMonth + 1 : $nd ) + $md + $rdcorr;
$rmcorr = $rd == 0 ? 0 : ( $rd > $daysInMonth ? 1 : -1 );
$rd = $rd % $daysInMonth;
}
echo "rd: " . $rd . "<br>";
echo "rmcorr: " . $rmcorr . "<br>";
$moff = 0;
$ycorr = 0;
if ( $my == $ny )
{
$rm = $mm - $nm + $mcorr;
}
else
{
$rm = 12 - ( $nm == 1 ? 13 : $nm ) + $mm + $mcorr;
$rycorr = $rm == 0 ? 0 : ( $rm > 12 ? 1 : -1 );
$rm = $rm % 12;
}
echo "rm: " . $rm . "<br>";
echo "rycorr: " . $rycorr . "<br>";
$ry = $my - $ny + $rycorr;
echo "ry: " . $ry . "<br><br>";
echo "result: $ry-$rm-$rd $rth:$rtm:$rts";
This will yield:
min: 01.02.1980 01:01:00
max: 02.01.2004 14:10:00
rts: 0
rtmcorr: 0
rtm: 9
rthcorr: 0
rth: 13
rdcorr: 0
daysInMonth: 29
daysInMonthCorrection: -1
rd: 1
rmcorr: -1
rm: 11
rycorr: -1
ry: 23
result: 23-11-1 13:9:0
Hope this helps.
If there are any bugs, please feel free to contact me and we will surely get it straight the next
time ;-)