note 77281 added to ref.datetime
| From: | carsten dot klein at abstraxion dot org | Date: | Wed, 22 Aug 2007 22:02:40 +0000 |
| Subject: | note 77281 added to ref.datetime | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-129710@lists.php.net to get a copy of this message | ||
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 ;-)
----
Server IP: 69.147.83.197
Probable Submitter: 87.79.48.197
----
Manual Page -- http://www.php.net/manual/en/ref.datetime.php
Edit -- https://master.php.net/note/edit/77281
Del: integrated -- https://master.php.net/note/delete/77281/integrated
Del: useless -- https://master.php.net/note/delete/77281/useless
Del: bad code -- https://master.php.net/note/delete/77281/bad+code
Del: spam -- https://master.php.net/note/delete/77281/spam
Del: non-english -- https://master.php.net/note/delete/77281/non-english
Del: in docs -- https://master.php.net/note/delete/77281/in+docs
Del: other reasons-- https://master.php.net/note/delete/77281
Reject -- https://master.php.net/note/reject/77281
Search -- https://master.php.net/manage/user-notes.php