note 39705 modified in function.mktime by didou
| From: | didou@php.net | Date: | Mon, 10 Jan 2005 03:22:29 +0000 |
| Subject: | note 39705 modified in function.mktime by didou | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-83027@lists.php.net to get a copy of this message | ||
<?php
//-----------------------------------------------------------
function date_diff($date_from,$date_to,$unit='d')
/*
Calculates difference from date_from to date_to, taking into account leap years
if date_from > date_to, the number of days is returned negative
date_from and date_to format is: "dd-mm-yyyy"
It can calculate ANY date difference, for example between 21-04-345 and 11-11-3412
This is possible by mapping any date to the "range 0" dates, as this table shows:
INI END RANGE LEAP YEARS
... ... ... ...
01/01/1920 01/01/1939 -3 5
01/01/1940 01/01/1959 -2 5
01/01/1960 01/01/1979 -1 5
01/01/1980 01/01/1999 0 5 * this is the range used for calculations with mktime
01/01/2000 01/01/2019 1 5
01/01/2020 01/01/2039 2 5
01/01/2040 01/01/2059 3 5
01/01/2060 01/01/2079 4 5
... ... ... ...
The difference is calculated in the unit specified by $unit (default is "days")
$unit:
'd' or 'D' = days
'y' or 'Y' = years
*/
{
//get parts of the dates
$date_from_parts = explode('-', $date_from);
$date_to_parts = explode('-', $date_to);
$day_from = $date_from_parts[0];
$mon_from = $date_from_parts[1];
$year_from = $date_from_parts[2];
$day_to = $date_to_parts[0];
$mon_to = $date_to_parts[1];
$year_to = $date_to_parts[2];
//if date_from is newer than date to, invert dates
$sign=1;
if ($year_from>$year_to) $sign=-1;
else if ($year_from==$year_to)
{
if ($mon_from>$mon_to) $sign=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $sign=-1;
}
if ($sign==-1) {//invert dates
$day_from = $date_to_parts[0];
$mon_from = $date_to_parts[1];
$year_from = $date_to_parts[2];
$day_to = $date_from_parts[0];
$mon_to = $date_from_parts[1];
$year_to = $date_from_parts[2];
}
switch ($unit)
{
case 'd': case 'D': //calculates difference in days
$yearfrom1=$year_from; //actual years
$yearto1=$year_to; //(yearfrom2 and yearto2 are used to calculate inside the range
"0")
//checks ini date
if ($yearfrom1<1980)
{//year is under range 0
$deltafrom=-floor((1999-$yearfrom1)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else if($yearfrom1>1999)
{//year is over range 0
$deltafrom=floor(($yearfrom1-1980)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else {//year is in range 0
$deltafrom=0;
$yearfrom2=$yearfrom1;
}
//checks end date
if ($yearto1<1980) {//year is under range 0
$deltato=-floor((1999-$yearto1)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else if($yearto1>1999) {//year is over range 0
$deltato=floor(($yearto1-1980)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else {//year is in range 0
$deltato=0;
$yearto2=$yearto1;
}
//Calculates the UNIX Timestamp for both dates (inside range 0)
$ts_from = mktime(0, 0, 0, $mon_from, $day_from, $yearfrom2);
$ts_to = mktime(0, 0, 0, $mon_to, $day_to, $yearto2);
$diff = ($ts_to-$ts_from)/86400;
//adjust ranges
$diff += 7305 * (($deltato-$deltafrom) / 20);
return $sign*$diff;
break;
case 'y': case 'Y': //calculates difference in years
$diff=$year_to-$year_from;
$adjust=0;
if ($mon_from>$mon_to) $adjust=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $adjust=-1;
return $sign*($diff+$adjust);
break;
}
}
?>
--was--
There is a correction to the function I published below, and an addition too. Now it can calculate
the difference in days, or in years, by using the parameter $unit (default is days)
Administrator, please remove the lower function, this is the good one.
//-----------------------------------------------------------
function date_diff($date_from,$date_to,$unit='d')
/*
Calculates difference from date_from to date_to, taking into account leap years
if date_from > date_to, the number of days is returned negative
date_from and date_to format is: "dd-mm-yyyy"
It can calculate ANY date difference, for example between 21-04-345 and 11-11-3412
This is possible by mapping any date to the "range 0" dates, as this table shows:
INI END RANGE LEAP YEARS
... ... ... ...
01/01/1920 01/01/1939 -3 5
01/01/1940 01/01/1959 -2 5
01/01/1960 01/01/1979 -1 5
01/01/1980 01/01/1999 0 5 * this is the range used for calculations with mktime
01/01/2000 01/01/2019 1 5
01/01/2020 01/01/2039 2 5
01/01/2040 01/01/2059 3 5
01/01/2060 01/01/2079 4 5
... ... ... ...
The difference is calculated in the unit specified by $unit (default is "days")
$unit:
'd' or 'D' = days
'y' or 'Y' = years
*/
{
//get parts of the dates
$date_from_parts = explode('-', $date_from);
$date_to_parts = explode('-', $date_to);
$day_from = $date_from_parts[0];
$mon_from = $date_from_parts[1];
$year_from = $date_from_parts[2];
$day_to = $date_to_parts[0];
$mon_to = $date_to_parts[1];
$year_to = $date_to_parts[2];
//if date_from is newer than date to, invert dates
$sign=1;
if ($year_from>$year_to) $sign=-1;
else if ($year_from==$year_to)
{
if ($mon_from>$mon_to) $sign=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $sign=-1;
}
if ($sign==-1) {//invert dates
$day_from = $date_to_parts[0];
$mon_from = $date_to_parts[1];
$year_from = $date_to_parts[2];
$day_to = $date_from_parts[0];
$mon_to = $date_from_parts[1];
$year_to = $date_from_parts[2];
}
switch ($unit)
{
case 'd': case 'D': //calculates difference in days
$yearfrom1=$year_from; //actual years
$yearto1=$year_to; //(yearfrom2 and yearto2 are used to calculate inside the range
"0")
//checks ini date
if ($yearfrom1<1980)
{//year is under range 0
$deltafrom=-floor((1999-$yearfrom1)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else if($yearfrom1>1999)
{//year is over range 0
$deltafrom=floor(($yearfrom1-1980)/20)*20; //delta t1
$yearfrom2=$yearfrom1-$deltafrom; //year used for calculations
}
else {//year is in range 0
$deltafrom=0;
$yearfrom2=$yearfrom1;
}
//checks end date
if ($yearto1<1980) {//year is under range 0
$deltato=-floor((1999-$yearto1)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else if($yearto1>1999) {//year is over range 0
$deltato=floor(($yearto1-1980)/20)*20; //delta t2
$yearto2=$yearto1-$deltato; //year used for calculations
}
else {//year is in range 0
$deltato=0;
$yearto2=$yearto1;
}
//Calculates the UNIX Timestamp for both dates (inside range 0)
$ts_from = mktime(0, 0, 0, $mon_from, $day_from, $yearfrom2);
$ts_to = mktime(0, 0, 0, $mon_to, $day_to, $yearto2);
$diff = ($ts_to-$ts_from)/86400;
//adjust ranges
$diff += 7305 * (($deltato-$deltafrom) / 20);
return $sign*$diff;
break;
case 'y': case 'Y': //calculates difference in years
$diff=$year_to-$year_from;
$adjust=0;
if ($mon_from>$mon_to) $adjust=-1;
else if ($mon_from==$mon_to)
if ($day_from>$day_to) $adjust=-1;
return $sign*($diff+$adjust);
break;
}
}
http://php.net/manual/en/function.mktime.php