Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Date and Time Functions

Date and Time Functions

Introduction

These functions allow you to get the date and time from the server where your PHP scripts are running. You can use these functions to format the date and time in many different ways.

Note:

Please keep in mind that these functions are dependent on the locale settings of your server. Make sure to take daylight saving time (use e.g. $date = strtotime('+7 days', $date) and not $date += 7*24*60*60) and leap years into consideration when working with these functions.

Note:

The timezones referenced in this section can be found in the Appendix J, List of Supported Timezones.

Requirements

No external libraries are needed to build this extension.

Installation

There is no installation needed to use these functions; they are part of the PHP core.

Note:

The latest version of the timezone database can be installed via PECL's » timezonedb. For Windows users, a pre-compiled DLL can be downloaded from the PECL4Win site: » php_timezonedb.dll.

Runtime Configuration

The behaviour of these functions is affected by settings in php.ini.

Table 39. Date/Time Configuration Options

Name Default Changeable Changelog
date.default_latitude "31.7667" PHP_INI_ALL Available since PHP 5.0.0.
date.default_longitude "35.2333" PHP_INI_ALL Available since PHP 5.0.0.
date.sunrise_zenith "90.583333" PHP_INI_ALL Available since PHP 5.0.0.
date.sunset_zenith "90.583333" PHP_INI_ALL Available since PHP 5.0.0.
date.timezone "" PHP_INI_ALL Available since PHP 5.1.0.


For further details and definitions of the PHP_INI_* constants, see the Appendix I, php.ini directives.

Here's a short explanation of the configuration directives.

date.default_latitude float

The default latitude.

date.default_longitude float

The default longitude.

date.sunrise_zenith float

The default sunrise zenith.

date.sunset_zenith float

The default sunset zenith.

date.timezone string

The default timezone used by all date/time functions if the TZ environment variable isn't set. The precedence order is described in the date_default_timezone_get() page. See Appendix J, List of Supported Timezones for a list of supported timezones.

Note:

The first four configuration options are currently only used by date_sunrise() and date_sunset().

Resource Types

This extension has no resource types defined.

Predefined Constants

The following constants are defined since PHP 5.1.1 and they offer standard date representations, which can be used along with the date format functions (like date()).

DATE_ATOM (string)
Atom (example: 2005-08-15T15:52:01+00:00)
DATE_COOKIE (string)
HTTP Cookies (example: Monday, 15-Aug-05 15:52:01 UTC)
DATE_ISO8601 (string)
ISO-8601 (example: 2005-08-15T15:52:01+0000)
DATE_RFC822 (string)
RFC 822 (example: Mon, 15 Aug 05 15:52:01 +0000)
DATE_RFC850 (string)
RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC)
DATE_RFC1036 (string)
RFC 1036 (example: Mon, 15 Aug 05 15:52:01 +0000)
DATE_RFC1123 (string)
RFC 1123 (example: Mon, 15 Aug 2005 15:52:01 +0000)
DATE_RFC2822 (string)
RFC 2822 (Mon, 15 Aug 2005 15:52:01 +0000)
DATE_RFC3339 (string)
Same as DATE_ATOM (since PHP 5.1.3)
DATE_RSS (string)
RSS (Mon, 15 Aug 2005 15:52:01 +0000)
DATE_W3C (string)
World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00)

Following constants exists since PHP 5.1.2 and specify a format returned by functions date_sunrise() and date_sunset().

SUNFUNCS_RET_TIMESTAMP (integer)
Timestamp
SUNFUNCS_RET_STRING (integer)
Hours:minutes (example: 08:02)
SUNFUNCS_RET_DOUBLE (integer)
Hours as floating point number (example 8.75)

Table of Contents

checkdate — Validate a Gregorian date
date_create — Returns new DateTime object
date_date_set — Sets the date
date_default_timezone_get — Gets the default timezone used by all date/time functions in a script
date_default_timezone_set — Sets the default timezone used by all date/time functions in a script
date_format — Returns date formatted according to given format
date_isodate_set — Sets the ISO date
date_modify — Alters the timestamp
date_offset_get — Returns the daylight saving time offset
date_parse — Returns associative array with detailed info about given date
date_sun_info — Returns an array with information about sunset/sunrise and twilight begin/end
date_sunrise — Returns time of sunrise for a given day and location
date_sunset — Returns time of sunset for a given day and location
date_time_set — Sets the time
date_timezone_get — Return time zone relative to given DateTime
date_timezone_set — Sets the time zone for the DateTime object
date — Format a local time/date
getdate — Get date/time information
gettimeofday — Get current time
gmdate — Format a GMT/UTC date/time
gmmktime — Get Unix timestamp for a GMT date
gmstrftime — Format a GMT/UTC time/date according to locale settings
idate — Format a local time/date as integer
localtime — Get the local time
microtime — Return current Unix timestamp with microseconds
mktime — Get Unix timestamp for a date
strftime — Format a local time/date according to locale settings
strptime — Parse a time/date generated with strftime()
strtotime — Parse about any English textual datetime description into a Unix timestamp
time — Return current Unix timestamp
timezone_abbreviations_list — Returns associative array containing dst, offset and the timezone name
timezone_identifiers_list — Returns numerically index array with all timezone identifiers
timezone_name_from_abbr — Returns the timezone name from abbrevation
timezone_name_get — Returns the name of the timezone
timezone_offset_get — Returns the timezone offset from GMT
timezone_open — Returns new DateTimeZone object
timezone_transitions_get — Returns all transitions for the timezone

Code Examples / Notes » ref.datetime

dkan

Zero-padding is easier to read and less complicated if you use the substr() function instead of an if-then statement.
function printtime() {
  $timenow = getdate();
  $hours = substr("0" . $timenow["hours"], -2);
  $minutes = substr("0" . $timenow["minutes"], -2);
  $seconds = substr("0" . $timenow["seconds"], -2);
  print($hours . " " . $minutes . " " . $seconds);
}


bgold

When debugging code that stores date/time values in a database, you may find yourself wanting to know the date/time that corresponds to a given unix timestamp, or the timestamp for a given date & time.
The following script will do the conversion either way.  If you give it a numeric timestamp, it will display the corresponding date and time.  If you give it a date and time (in almost any standard format), it will display the timestamp.
All conversions are done for your locale/time zone.
<?
       while (true)
       {
               // Read a line from standard in.
               echo "enter time to convert: ";
               $inline = fgets(STDIN);
               $inline = trim($inline);
               if ($inline == "" || $inline == ".")
                       break;
               // See if the line is a date.
               $pos = strpos($inline, "/");
               if ($pos === false) {
                       // not a date, should be an integer.
                       $date = date("m/d/Y G:i:s", $inline);
                       echo "int2date: $inline -> $date\n";
               } else {
                       $itime = strtotime($inline);
                       echo "date2int: $inline -> $itime\n";
               }
       }
?>


herbert dot fischer att gee mail dot com

Updating internal's PHP timezone database (5.1.x and 5.2.x)
http://fischer.tecnologia.ws/en/node/1
[editor: Although this does work, it's often easier just to install the pecl timezonedb extension - they should be up-to-date with the latest possible information]


carsten dot klein

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 . "
";
echo "max: " . $max . "
";
$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 . "
";
echo "rtmcorr: " . $rtmcorr . "
";
// 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 . "
";
echo "rthcorr: " . $rthcorr . "
";
// 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 . "
";
echo "rdcorr: " . $rdcorr . "
";
$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 . "
";
echo "daysInMonthCorrection: " . $daysInMonthCorrection . "
";
$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 . "
";
echo "rmcorr: " . $rmcorr . "
";
$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 . "
";
echo "rycorr: " . $rycorr . "
";
$ry = $my - $ny + $rycorr;
echo "ry: " . $ry . "
";
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 ;-)


datavortex

This is a litttle function I cobbled together from my own code, and snippets from this site to calculate the difference between two datetimes without having to confine it to simply one interval.  This will tell you how many weeks, days, hours, minutes, and seconds there are between the given datetimes, and also makes a little English string you can use.
This could easily be expanded to include months, and years, but I didn't want to have to deal with any of the leap year and variable month length stuff.
<?
function dateDiff($dateTimeBegin,$dateTimeEnd) {
 $dateTimeBegin =strtotime($dateTimeBegin);
 $dateTimeEnd   =strtotime($dateTimeEnd);
 if($dateTimeEnd === -1 || $dateTimeBegin === -1) {
   # error condition
   return false;
 }
 $diff = $dateTimeEnd - $dateTimeBegin;
 if ($diff < 0) {
   # error condition
   return false;
 }
 $weeks = $days = $hours = $minutes = $seconds = 0; # initialize vars
 if($diff % 604800 > 0) {
   $rest1   = $diff % 604800;
   $weeks   = ($diff - $rest1) / 604800; # seconds a week
   if($rest1 % 86400 > 0) {
     $rest2 = ($rest1 % 86400);
     $days  = ($rest1 - $rest2) / 86400; # seconds a day
     if( $rest2 % 3600 > 0 ) {
       $rest3 = ($rest2 % 3600);
       $hours = ($rest2 - $rest3) / 3600; # seconds an hour
       if( $rest3 % 60 > 0 ) {
         $seconds = ($rest3 % 60);
         $minutes = ($rest3 - $seconds) / 60;  # seconds a minute
       } else {
         $minutes = $rest3 / 60;
       }
     } else {
       $hours = $rest2 / 3600;
     }
   } else {
     $days = $rest1/ 86400;
   }
 }else {
   $weeks = $diff / 604800;
 }
 $string = array();
 if($weeks > 1) {
   $string[]  = "$weeks weeks";
 } elseif ($weeks == 1) {
   $string[]  = "a week";
 }
 if($days > 1) {
   $string[] = "$days days";
 } elseif($days == 1) {
   $string[] = "a day";
 }
 if($hours > 1) {
   $string[] = "$hours hours";
 } elseif ($hours == 1) {
   $string[] = "an hour";
 }
 if($minutes > 1) {
   $string[] = "$minutes minutes";
 } elseif ($minutes == 1) {
   $string[] = "a minute";
 }
 if($seconds > 1) {
   $string[] = "$seconds seconds";
 } elseif($seconds == 1) {
   $string[] = "a second";
 }
 # join together all the strings in the array above except the last element
 $text  = join(', ', array_slice($string,0,sizeof($string)-1)) . ", and ";
 $text .= array_pop($string);  # put the last one on after the and
 
 return array($text, $weeks, $days, $hours, $minutes, $seconds);
?>


info

This is a function to convert a mysql-datetime to an unix-timestamp.
function mysqlDatetimeToUnixTimestamp($datetime){
$val = explode(" ",$datetime);
$date = explode("-",$val[0]);
$time = explode(":",$val[1]);
return mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}


balin

this function count days between $start and $end dates in mysql format (yyyy-mm-dd)
if one of paramters is 0000-00-00 will return 0
$start date must be less then $end
<?
//For Count Days
function count_days($start, $end)
{
   if( $start != '0000-00-00' and $end != '0000-00-00' )
   {
       $timestamp_start = strtotime($start);
       $timestamp_end = strtotime($end);
       if( $timestamp_start >= $timestamp_end ) return 0;
       $start_year = date("Y",$timestamp_start);
       $end_year = date("Y", $timestamp_end);
       $num_days_start = date("z",strtotime($start));
       $num_days_end = date("z", strtotime($end));
       $num_days = 0;
       $i = 0;
       if( $end_year > $start_year )
       {
          while( $i < ( $end_year - $start_year ) )
          {
             $num_days = $num_days + date("z", strtotime(($start_year + $i)."-12-31"));
             $i++;
          }
        }
        return ( $num_days_end + $num_days ) - $num_days_start;
   }
   else
   {
        return 0;
    }
}
?>


daniel

This dateDiff() function can take in just about any timestamp, including UNIX timestamps and anything that is accepted by strtotime(). It returns an array with the ability to split the result a couple different ways. I built this function to suffice any datediff needs I had. Hope it helps others too.
<?php
 /********* dateDiff() function **********
  * returns Array of Int values for difference between two dates
  * $date1 > $date2 --> positive integers are returned
  * $date1 < $date2 --> negative integers are returned
  *
  * $split recognizes the following:
  *   'yw' = splits up years, weeks and days (default)
  *   'y'  = splits up years and days
  *   'w'  = splits up weeks and days
  *   'd'  = total days
  *
  * examples:
  *   $dif1 = dateDiff() or dateDiff('yw')
  *   $dif2 = dateDiff('y')
  *   $dif3 = dateDiff('w')
  *   $dif4 = dateDiff('d')
  *
  * assuming dateDiff returned 853 days, the above
  * examples would have a print_r output of:
  *   $dif1 == Array( [y] => 2 [w] => 17 [d] => 4 )
  *   $dif2 == Array( [y] => 2 [d] => 123 )
  *   $dif3 == Array( [w] => 121 [d] => 6 )
  *   $dif4 == Array( [d] => 847 )
  *
  * note: [h] (hours), [m] (minutes), [s] (seconds) are always returned as elements of the Array
  */
 function dateDiff($dt1, $dt2, $split='yw') {
   $date1 = (strtotime($dt1) != -1) ? strtotime($dt1) : $dt1;
   $date2 = (strtotime($dt2) != -1) ? strtotime($dt2) : $dt2;
   $dtDiff = $date1 - $date2;
   $totalDays = intval($dtDiff/(24*60*60));
   $totalSecs = $dtDiff-($totalDays*24*60*60);
   $dif['h'] = $h = intval($totalSecs/(60*60));
   $dif['m'] = $m = intval(($totalSecs-($h*60*60))/60);
   $dif['s'] = $totalSecs-($h*60*60)-($m*60);
   // set up array as necessary
   switch($split) {
   case 'yw': # split years-weeks-days
     $dif['y'] = $y = intval($totalDays/365);
     $dif['w'] = $w = intval(($totalDays-($y*365))/7);
     $dif['d'] = $totalDays-($y*365)-($w*7);
     break;
   case 'y': # split years-days
     $dif['y'] = $y = intval($totalDays/365);
     $dif['d'] = $totalDays-($y*365);
     break;
   case 'w': # split weeks-days
     $dif['w'] = $w = intval($totalDays/7);
     $dif['d'] = $totalDays-($w*7);
     break;
   case 'd': # don't split -- total days
     $dif['d'] = $totalDays;
     break;
   default:
     die("Error in dateDiff(). Unrecognized \$split parameter. Valid values are 'yw', 'y', 'w', 'd'. Default is 'yw'.");
   }
   return $dif;
 }
?>


jens

There is an error in vincentv's post from 07-Feb-2001 11:23:
In function dayDiff(..) the return statement must be replaced by:
<?
return ( (getYear($timestamp1)*365 + $dayInYear1) -
        (getYear($timestamp2)*365 + $dayInYear2) );
?>


teddk

There is an an excellent article by Allan Kent on PHP date/time. The full article can be found at:
http://www.phpbuilder.net/columns/akent20000610.php3


charles

There are two dates that I know of that produce an incorrect result for the date functions above: 2004-04-04 and 2004-04-05. The days difference is zero instead of one.

slash

The post below has been edited saying there is a bug line 12 and 13 and proposition a solution. I think there was no
bug in the original post.
menaurus at gmx dot de
16-Jul-2003 01:37
The argument has to be in the standard mysql format (y-m-d)...
function age($date) {
if (!$date) return false;
$year=0+substr($date,0,4);
$month=0+substr($date,5,2);
$day=0+substr($date,8,2);
$t=0;
$d=date("d");
$m=date("m");
$y=date("Y");
$age=$y-$year;
if ($m<$month) $t=-1;
else if ($m==$month) if ($d<$day) $t=-1;
return ($age+$t);
}
this funktion has got a little bug:
On Line 12 and 13...
Bugfix:
12 if ($month<$m) $t=-1;
13 else if ($m==$month AND $day<$d) $t=-1;


menaurus

The argument has to be in the standard mysql format (y-m-d)...
function age($date) {
if (!$date) return false;
$year=0+substr($date,0,4);
$month=0+substr($date,5,2);
$day=0+substr($date,8,2);
$t=0;
$d=date("d");
$m=date("m");
$y=date("Y");
$age=$y-$year;
if ($m<$month) $t=-1;
else if ($m==$month) if ($d<$day) $t=-1;
return ($age+$t);
}
this funktion has got a little bug:
On Line 12 and 13...
Bugfix:
12 if ($month<$m) $t=-1;
13 else if ($m==$month AND $day<$d) $t=-1;


php-contrib

Someone may find this info of some use:
Rules for calculating a leap year:
1) If the year divides by 4, it is a leap year (1988, 1992, 1996 are leap years)
2) Unless it divides by 100, in which case it isn't (1900 divides by 4, but was not a leap year)
3) Unless it divides by 400, in which case it is actually a leap year afterall (So 2000 was a leap year).
In practical terms, to work out the number of days in X years, multiply X by 365.2425, rounding DOWN to the last whole number, should give you the number of days.
The result will never be more than one whole day inaccurate, as opposed to multiplying by 365, which, over more years, will create a larger and larger deficit.


mindaugas

Some lines about LeapYear and day count of month:
   function mod($a,$b)
   {
   $x1=(int) abs($a/$b);
   $x2=$a/$b;
   return $a-($x1*$b);    
   }    
   function IsLeapYear($dt)
   {
   $y=$dt["year"];
   $bulis=((mod($y,4)==0) && ((mod ($y,100)<>0) || (mod($y,400)==0)));
   return $bulis;
   }
   function daycount($dt)
   {
   $dc_year=$dt["year"];
   $dc_month=$dt["mon"];
   $dc_day=$dt["mday"];
switch ($dc_month)
{
case  1:
case  3:
case  5:
case  7:
case  8:
case 10:
case 12:
       return 31;
break;
case  4:
case  6:
case  9:
case 11:
       return 30;
break;
case 2:
if (IsLeapYear($dt)) { return 28; } else { return 29; };
break;
}
   }


vincentv

Some general date functions.
function sub($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
$mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
return $timestamp - $mytime;
}
function add($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
$mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
return $timestamp + $mytime;
}
function dayOfWeek($timestamp) {
return intval(strftime("%w",$timestamp));
}
function daysInMonth($timestamp) {
$timepieces = getdate($timestamp);
$thisYear   = $timepieces["year"];
$thisMonth = $timepieces["mon"];

for($thisDay=1;checkdate($thisMonth,$thisDay,$thisYear);$thisDay++);

return $thisDay;
}
function firstDayOfMonth($timestamp) {
$timepieces = getdate($timestamp);
return mktime( $timepieces["hours"],
$timepieces["minutes"],
$timepieces["seconds"],
$timepieces["mon"],
1,
$timepieces["year"]);
}
function monthStartWeekDay($timestamp) {
return dayOfWeek(firstDayOfMonth($timestamp));
}
function weekDayString($weekday) {
$myArray = Array( 0 => "Sun",
1 => "Mon",
2 => "Tue",
3 => "Wed",
4 => "Thu",
5 => "Fri",
6 => "Sat");
return $myArray[$weekday];
}
function stripTime($timestamp) {
$timepieces = getdate($timestamp);
return mktime( 0,
0,
0,
$timepieces["mon"],
$timepieces["mday"],
$timepieces["year"]);
}
function getDayOfYear($timestamp) {
$timepieces = getdate($timestamp);
return intval($timepieces["yday"]);
}
function getYear($timestamp) {
$timepieces = getdate($timestamp);
return intval($timepieces["year"]);
}
function dayDiff($timestamp1,$timestamp2) {
$dayInYear1 = getDayOfYear($timestamp1);
$dayInYear2 = getDayOfYear($timestamp2);
return ((getYear($dayInYear1)*365 + $dayInYear1) -
(getYear($dayInYear2)*365 + $dayInYear2));
}
hope they are usefull to you.
- Vincent


carsten dot klein

Regarding the routine below that should have correctly calculated the duration between two dates:
The author of the below posting should have tested the code better, erm...
The code partly works, but: it does blatantly fail in a very few specific scenarios, therefore I'd like to have the below posting and this one removed. The below since it is actually unusable (I will post the corrected version as soon as I have it up and running) since it will calculate wrong values in cases where the month February is involved.
In that case, either the years are calculated incorrectly or there is a difference in the calculated months a/o days.
Please remove, thanks and sorry for the inconvenience. I will repost the corrected version asap.
Regards
Carsten


wes9999

Regarding the dateDiff function submitted by andreencinas at yahoo dot com dot br:
http://us3.php.net/manual/en/ref.datetime.php#57251
A daylight savings time problem was discovered when doing the datediff (in days) on 4/1/2005 and 5/1/2005, for example.
I expected to get 30 days, but instead I got 29 days.  This was due to the fact that dateDiff uses strtotime on each of these dates, then subtracts them, then divides by 86400 to get days.  The resulting difference is 29.958333333333, and then the function takes the floor of this number, producing 29.
The reason for this is that an hour of time is lost during the switch to DST.
A quick solution is to replace floor() with round(), but I'm open to other solutions.


xiven

One thing PHP really lacks IMHO is an equivalent of ASP's "DateDiff" function.  Here's a function that comes close to duplicating the functionality:
<?php
function datediff($interval, $date1, $date2) {
// Function roughly equivalent to the ASP "DateDiff" function
$seconds = $date2 - $date1;

switch($interval) {
case "y":
list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = $year2 - $year1;
if($month1 > $month2) {
$diff -= 1;
} elseif($month1 == $month2) {
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
}
break;
case "m":
list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
break;
case "w":
// Only simple seconds calculation needed from here on
$diff = floor($seconds / 604800);
break;
case "d":
$diff = floor($seconds / 86400);
break;
case "h":
$diff = floor($seconds / 3600);
break;        
case "i":
$diff = floor($seconds / 60);
break;        
case "s":
$diff = $seconds;
break;        
}    
return $diff;
}
?>


koch.ro

Not really elegant, but tells you, if your installed timezonedb is the most recent:
class TestDateTimeTimezonedbVersion extends PHPUnit_Framework_TestCase
{
   public function testTimezonedbIsMostRecent()
   {
       ini_set( 'date.timezone', 'Europe/Berlin' );
       ob_start();                                                                                                        
       phpinfo(INFO_MODULES);
       $info = ob_get_contents();                                                                                        
       ob_end_clean();
       $start = strpos( $info, 'Timezone Database Version' ) + 29;
       $this->assertTrue( FALSE !== $start, 'Seems there is no timezone DB installed' );
       $end   = strpos( $info, "\n", $start );
       $installedVersion = substr( $info, $start, $end - $start );
       exec( 'pecl remote-info timezonedb', &$output );
       $availableVersion = substr( $output[2], 12 );
       $this->assertEquals( $availableVersion, $installedVersion,
       'The installed timezonedb is not actual. Installed: '.$installedVersion
       .' available: '.$availableVersion
       );
   }
}


venoel

May be useful for somebody. This function takes on daylight saving time
Function DateDiff($date1,$date2) {
 $timedifference=$date2-$date1;
 $corr=date("I",$date2)-date("I",$date1);
 $timedifference+=$corr;
 return $timedifference;
}
Example:
$d1=mktime(2,0,0,10,28,2007);
$d2=mktime(4,0,0,10,28,2007);
$period=DateDiff($d1,$d2);
printf("
%s",date("I d.m.Y H:i",$d1));
printf("
%u hour",$period/3600);
printf("
%s",date("I d.m.Y H:i",$d2));
Getting 2 hour instead 3.


pk_jsp

Just want to add a comment to the function datediff given by Xiven that simple difference of 2 dates as in
$seconds = $date2 - $date1; will nor work instead the following need to be used.
$seconds = strtotime($date2) - strtotime($date1);


ruby

just modified from Xiven
function datediff($interval, $date1, $date2) {
  // Function roughly equivalent to the ASP "DateDiff" function
 
  //set the date format first
  $date1= date("Y-m-d", strtotime($date1));
  $date2= date("Y-m-d",strtotime($date2));
 
  $seconds = $date2 - $date1;
 
  switch($interval) {
      case "y":
          list($year1, $month1, $day1) = split('-', $date1);
          list($year2, $month2, $day2) = split('-', $date2);
          $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
          $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
          $diff = $year2 - $year1;
          if($month1 > $month2) {
              $diff -= 1;
          } elseif($month1 == $month2) {
              if($day1 > $day2) {
                  $diff -= 1;
              } elseif($day1 == $day2) {
                  if($time1 > $time2) {
                      $diff -= 1;
                  }
              }
          }
          break;
      case "m":
          list($year1, $month1, $day1) = split('-', $date1);
          list($year2, $month2, $day2) = split('-',$date2);
          $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
          $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
          $diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
          if($day1 > $day2) {
              $diff -= 1;
          } elseif($day1 == $day2) {
              if($time1 > $time2) {
                  $diff -= 1;
              }
          }
          break;
      case "w":
          // Only simple seconds calculation needed from here on
          $diff = floor($seconds / 604800);
          break;
      case "d":
          $diff = floor($seconds / 86400);
          break;
      case "h":
          $diff = floor($seconds / 3600);
          break;        
      case "i":
          $diff = floor($seconds / 60);
          break;        
      case "s":
          $diff = $seconds;
          break;        
  }
  //return the +ve integer only
  if ($diff <0)
  {
  $diff= 0-$diff;
  }
  return $diff;
}


james

info at flash-ultra dot de, you could just use UNIX_TIMESTAMP(DATE) in your SQL query.

mwedgwood

In vincentv's examples, you should use gmmktime instead of mktime for portability across time zones. For example:
function DateSub($timestamp, $unit, $amount) {
// Possible $units are: "hr", "min", "sec",
//          "mon", "day", or "yr"
// $amount should be an integer
   $delta_vars = array("hr"=>0, "min"=>0,
"sec"=>0, "mon"=>1,
"day"=>1,"yr"=>1970);
   $delta_vars[$unit] += $amount;
   $delta = gmmktime($delta_vars["hr"],
$delta_vars["min"],
$delta_vars["sec"],
$delta_vars["mon"],
$delta_vars["day"],
$delta_vars["yr"]);
   return $timestamp - $delta;
}


codeduck

in reply to dkan at netscreen dot com 29-Aug-2003 07:40
> Zero-padding is easier to read and less complicated if you
> use the substr() function instead of an if-then statement.
my two versions of printtime with padding:
<?
function printtime() {
  $timenow = getdate();
  printf(
     '%02d %02d %02d',
     $timenow["hours"],
     $timenow["minutes"],
     $timenow["seconds"]
  );
}
?>
or the better one:
<?
function printtime() {
  echo date('H i s');
}
?>


asg

If you like to have the last day of the current month, try this oneliner:
$lastday = strftime ("%d.%m.%Y", (mktime (0,0,0,(date(m)+1),0,(date(Y)))));
-


bitbuster

If you have to compare timestamps, I suggest you do it inside the database.. postgres, for example, allows statements like this:
select (current_timestamp < (select zeitdatum from time_test where zahl=5) );


jmpz art jmpz dort org

If you are dealing with a date in a database, you could just use the mysql function DATEDIFF(expr1,expr2) To calculate the difference without big bulky php functions.

aquatakat

I wrote a simple script to format a duration in seconds. Give the function some value in seconds and it will return an array.
<?php
function format_duration($seconds) {
$periods = array(
'centuries' => 3155692600,
'decades' => 315569260,
'years' => 31556926,
'months' => 2629743,
'weeks' => 604800,
'days' => 86400,
'hours' => 3600,
'minutes' => 60,
'seconds' => 1
);
$durations = array();
foreach ($periods as $period => $seconds_in_period) {
if ($seconds >= $seconds_in_period) {
$durations[$period] = floor($seconds / $seconds_in_period);
$seconds -= $durations[$period] * $seconds_in_period;
}
}

return $durations;
}
echo format_duration(864);
/*
[minutes] => 14
[seconds] => 24
*/
echo format_duration(3600);
/*
[hours] => 1
*/
echo format_duration(11111111);
/*
[months] => 4
[days] => 6
[hours] => 20
[minutes] => 28
[seconds] => 59
*/
?>


joey dot garcia

I was trying to make a Month-At-A-Glance and I finally got it to work so I thought I'd share it too.  What you need to get this to work is the "Day Of The Week Number", i.e., Sunday=1 and the "Number Of Days in the Month".  I also used Allan Kent's Date/Time Column at PHPBuilder to get the required information.  I also added the process I used to the requried information.
Enjoy!
<html>
<head>
<title>Month-At-A-Glance</title>
</head>
<body>
<?php
// *** These are here if you need to calculate the required values ***
// *** Reference Allan Kent's Column on Dates at PHPBuilder.com
//$thismonth =  mktime($hours, $minutes,$seconds ,$month, $day,$year);
//$firstday =  mktime($hours, $minutes,$seconds ,$month, 1,$year);
//$dayofweek=date("D",$thismonth);
//$firstdayofmonth=date("D",$firstday);
//$weekdaynum=array("Sun"=>1, "Mon"=>2, "Tue"=>3, "Wed"=>4, "Thu"=>5, "Fri"=>6, "Sat"=>7);
//$dayNumber=$weekdaynum[$dayofweek];
print "<table width=80% align=center border=1>\n";
print"<tr><th>Sun(1)</th> <th>Mon(2)</th> <th>Tue(3)</th> <th>Wed(4)</th> <th>Thu(5)</th> <th>Fri(6)</th> <th>Sat(7)</th> </tr>";
$daysinmonth=31;//For July 2000 this is 31 days
$daycount=1;
$firstdayofmonth=7;//For July 2000 this is Sat, or day 7
for ($week=1; $week <= 6; $week++){
print"<tr>\n";
  for($day=1; $day <=7; $day++){
       if( ($day >= $firstdayofmonth) || ($week >1) ){
           print"<td height=40px>";
               if ($daycount <= $daysinmonth){
                   print $daycount;
$daycount++;
               }
           print"&nbsp;</td>\n";
       }
       else{
           print"<td height=40px> &nbsp; </td>\n";
       }
   }
print"\n</tr>\n";
}
print"</table>";
?>
</body>
</html>


darren edwards

I was looking for a solution where I could return the number of days, hours, Minutes and seconds between two entries in a table.
DATE_DIFF is not running on my mysql server as my provider uses mysql version 4.0.25
Solution was to use to days and std time functions to calculate the difference in one call.
The fields stored in the table(report_table) are
time(00:00:00),
date(0000-00-00) and record(enum) which tells the app the type of log stored. EG start or end of a report.
SELECT
(TO_DAYS( `end`.`date` ) - TO_DAYS( `start`.`date` ))
-
( second( `end`.`time` ) + (minute( `end`.`time` )*60) + (hour( `end`.`time` )*3600)
<
second( `start`.`time` ) + (minute( `start`.`time` )*60) + (hour( `start`.`time` )*3600))
AS `days` ,
SEC_TO_TIME(
(second( `end`.`time` ) + (minute( `end`.`time` )*60) + (hour( `end`.`time` )*3600) )
-
(second( `start`.`time` ) + (minute( `start`.`time` )*60) + (hour( `start`.`time` )*3600) )
) AS `hms`,
`start`.`time` as `start`,
`end`.`time`  as `end`
FROM `report_table` AS `start` , `report_table` AS `end`
AND `start`.`record` = 'Report Begin'
AND `end`.`record` = 'Report End'
LIMIT 1
If there is no end of report then it will not return a result, as you would expect.


eric z ezsomething

I was having a horrible time trying to get a good list of timezones, how to set them locally (for the user/client), and how best to keep this information. Building on the notes of this site (thanks everyone), I constructed code that should work on just about any un*x based platform.  It reads the local timezone table and gives your a nested array of the continents and regions of the file -- the natural continent sorting is even by the most populated areas (thanks Paul Eggert!).
Afterwards, all you have to do is export the timezone string with an environmental set.. which works just fine if php is running as an apache model; haven't tested it for commandline, but I suspect it's okay there, too.
<?php
if (isset($_SESSION[PROFILE_TZOFFSET]))
       putenv('TZ='.$_SESSION[PROFILE_TZOFFSET]);
?>
Here's how to load the timezones... the nested array makes it easy to insert into html lists or other well-behaved objects.
<?php
   function getTimezoneData() {
     //EricZ - 9/1/05 - free to use, keep the comments :)
     $zoneNames = array();
     // -- first part, gather all of the zone data
     $zoneSource = '/usr/share/zoneinfo/zone.tab';
     $zoneHandle = fopen($zoneSource, "r");
     if (!$zoneHandle) return NULL;                  //bad file, abort now
     while (!feof($zoneHandle)) {
       $zoneLine = ltrim(fgets($zoneHandle, 4096));
       if ($zoneLine[0]=='#')  continue;           //skip comments
        //Columns...
        // 1.  ISO 3166 2-character country code.
        // 2.  Latitude and longitude of the zone's principal location
        // 3.  Zone name used in value of TZ environment variable.
        // 4.  Comments; present if and only if country has multiple rows.
       $zoneParts = explode("\t",$zoneLine);       //grab parts
       if (count($zoneParts) < 3) continue;       //erroneous line!
       $nameParts = explode('/', $zoneParts[2], 2);   //grab country/name
       $zoneKey = $nameParts[0];                   //country or area
       $insertArray = &$zoneNames;                 //where to insert?
       if (count($nameParts) > 1) {                //area/populous
         if (!isset($zoneNames[$zoneKey]))         //not set before
           $zoneNames[$zoneKey] = array();
         $insertArray = &$zoneNames[$zoneKey];     //grab sub (country)
         $zoneKey = trim($nameParts[1]);           //grab correct key
       }
       $zoneKey = preg_replace('/[_]/',' ', $zoneKey);
       $insertArray[$zoneKey] = trim($zoneParts[2]); //actually set data
     }                                             //end while not eof
     fclose($zoneHandle);
     return $zoneNames;
   }
?>


nightowl

I wanted to find all records in my database which match the current week (for a call-back function). I made up this function to find the start and end of the current week :
function week($curtime) {

$date_array = getdate (time());
$numdays = $date_array["wday"];

$startdate = date("Y-m-d", time() - ($numdays * 24*60*60));
$enddate = date("Y-m-d", time() + ((7 - $numdays) * 24*60*60));
$week['start'] = $startdate;
$week['end'] = $enddate;

return $week;

}


nickaubert

I ran into an issue using a function that loops through an array of dates where the keys to the array are the Unix timestamp for midnight for each date.  The loop starts at the first timestamp, then incremented by adding 86400 seconds (ie. 60 x 60 x 24).  However, Daylight Saving Time threw off the accuracy of this loop, since certain days have a duration other than 86400 seconds.  I worked around it by adding a couple of lines to force the timestamp to midnight at each interval.
<?php
 $ONE_DAY = 90000;   // can't use 86400 because some days have one hour more or less
 for ( $each_timestamp = $start_time ; $each_timestamp <= $end_time ; $each_timestamp +=  $ONE_DAY) {
   /*  force midnight to compensate for daylight saving time  */
   $this_timestamp_array = getdate( $each_timestamp );
   $each_timestamp = mktime ( 0 , 0 , 0 , $this_timestamp_array[mon] , $this_timestamp_array[mday] , $this_timestamp_array[year] );
    // do some stuff...
 }
?>


garyc

I needed to calculate the week number from a given date and vice versa, where the week starts with a Monday and the first week of a year may begin the year before, if the year begins in the middle of the week (Tue-Sun). This is the way weekly magazines calculate their issue numbers.
Here are two functions that do exactly that:
Hope somebody finds this useful.
Gary
/*  w e e k n u m b e r  -------------------------------------- //
weeknumber returns a week number from a given date (>1970, <2030)
Wed, 2003-01-01 is in week 1
Mon, 2003-01-06 is in week 2
Wed, 2003-12-31 is in week 53, next years first week
Be careful, there are years with 53 weeks.
// ------------------------------------------------------------ */
function weeknumber ($y, $m, $d) {
$wn = strftime("%W",mktime(0,0,0,$m,$d,$y));
$wn += 0; # wn might be a string value
$firstdayofyear = getdate(mktime(0,0,0,1,1,$y));
if ($firstdayofyear["wday"] != 1) # if 1/1 is not a Monday, add 1
$wn += 1;
return ($wn);
} # function weeknumber
/*  d a t e f r o m w e e k  ---------------------------------- //
From a weeknumber, calculates the corresponding date
Input: Year, weeknumber and day offset
Output: Exact date in an associative (named) array
2003, 12, 0: 2003-03-17 (a Monday)
1995,  53, 2: 1995-12-xx
...
// ------------------------------------------------------------ */
function datefromweek ($y, $w, $o) {
$days = ($w - 1) * 7 + $o;
$firstdayofyear = getdate(mktime(0,0,0,1,1,$y));
if ($firstdayofyear["wday"] == 0) $firstdayofyear["wday"] += 7;
# in getdate, Sunday is 0 instead of 7
$firstmonday = getdate(mktime(0,0,0,1,1-$firstdayofyear["wday"]+1,$y));
$calcdate = getdate(mktime(0,0,0,$firstmonday["mon"], $firstmonday["mday"]+$days,$firstmonday["year"]));
$date["year"] = $calcdate["year"];
$date["month"] = $calcdate["mon"];
$date["day"] = $calcdate["mday"];
return ($date);
} # function datefromweek


brighn a yahoo . com

I needed a function that determined the last Sunday of the month. Since it's made for the website's "next meeting" announcement, it goes based on the system clock; also, if today is between Sunday and the end of the month, it figures out the last Sunday of *next* month. lastsunday() takes no arguments and returns the date as a string in the form "January 26, 2003". I could probably have streamlined this quite a bit, but at least it's transparent code. =)
 /* The two functions calculate when the next meeting will
    be, based on the assumption that the meeting will be on
    the last Sunday of the month. */  
 function getlast($mon, $year) {
   $daysinmonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
   $days = $daysinmonth[$mon-1];
   if ($mon == 2 && ($year % 4) == 0 && (($year % 100) != 0 ||
   ($year % 400) == 0)) $days++;
   if ($mon == 2 && ($year % 4) == 0 && ($year % 1000) != 0) $days++;
   $lastday = getdate(mktime(0,0,0,$mon,$days,$year));
   $wday = $lastday['wday'];
   return getdate(mktime(0,0,0,$mon,$days-$wday,$year));
 }
 function lastsunday() {
   $today = getdate();
   $mon = $today['mon'];
   $year = $today['year'];
   $mday = $today['mday'];
   $lastsun = getlast($mon, $year);
   $sunday = $lastsun['mday'];
   if ($sunday < $mday) {
     $mon++;
     if ($mon = 13) {
       $mon = 1;
       $year++;
     }
     $lastsun = getlast($mon, $year);
     $sunday = $lastsun['mday'];
   }
   $nextmeeting = getdate(mktime(0,0,0,$mon,$sunday,$year));
   $month = $nextmeeting['month'];
   $mday = $nextmeeting['mday'];
   $year = $nextmeeting['year'];
   return "$month $mday, $year";
 }


th

I had some problems with dates between mySQL and PHP.  PHP had all these great date functions but I wanted to store a usable value in my database tables. In this case I was using TIMESTAMP(14)  <or 'YYYYMMDDHHMMSS'>.
This is perhaps the easiest way I have found to pull the PHP usable UNIX Datestamp from my mySQL datestamp stored in the tables:
Use the mySQL UNIX_TIMESTAMP() function in your SQL definition string. i.e.
$sql= "SELECT field1, field2, UNIX_TIMESTAMP(field3) as your_date
         FROM your_table
         WHERE field1 = '$value'";
The query will return a temp table with coulms "field1" "Field2" "your_date"
The "your_date" will be formatted in a UNIX TIMESTAMP!  Now you can use the PHP date() function to spew out nice date formats.
Sample using above $sql:
20010111002747  = Date Stored on mySQL table (TIMESTAMP(14))
979172867  = value returned as your_date in sql stmt (UNIX_TIMESTAMP)
if we use $newdate = date("F jS, Y -- g:ia", $row["your_date"]);
  --(after fetching our array from the sql results of course)--
echo "$newdate";              --Will produce:
January 11th, 2001 -- 12:27am
Hope this helps someone out there!


rugby7s

I had same problem nickaubert  had with trying to compute timestamp for a span of dates that was daylight savings compliant.
OLD CODE:
/***********************************************
*Note - This is the old code that doesn't handle daylights savings time
***********************************************/
for($i=$start_date; $i<=$end_date; $i=($i+(24*60*60))){
//--- DO something $i is timestamp
}

NEW CODE:
for($i=$start_date;$i<=$end_date;
$i=(mktime(0,0,0,date('n',$i),date('d',$i)+1,date('Y',$i)))){
//--- DO something $i is timestamp
}


elizalde baguinon

I evaluated the modified version of Xiven's datediff (below) and I saw some errors. I switched the lines of getting the seconds and the formatting of date. I was testing the datediff() function with a "d" interval. Here I added my test code.
$dateA = "2004-12-31";
$dateB = "2005-01-01";
function datediff($interval, $date1, $date2) {
  // Function roughly equivalent to the ASP "DateDiff" function
 
  /* Get the seconds first */
  $seconds = strtotime($date2) - strtotime($date1);
  $date1=date("Y-m-d", strtotime($date1));
  $date2=date("Y-m-d",strtotime($date2));
 
  switch($interval) {
      case "y":
          list($year1, $month1, $day1) = split('-', $date1);
          list($year2, $month2, $day2) = split('-', $date2);
          $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
          $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
          $diff = $year2 - $year1;
          if($month1 > $month2) {
              $diff -= 1;
          } elseif($month1 == $month2) {
              if($day1 > $day2) {
                  $diff -= 1;
              } elseif($day1 == $day2) {
                  if($time1 > $time2) {
                      $diff -= 1;
                  }
              }
          }
          break;
      case "m":
          /* parses the year, month and days. split() was replaced with explode(), PHP Manual says it's faster */
  list($year1, $month1, $day1) = explode('-', $date1);
          list($year2, $month2, $day2) = explode('-',$date2);
          $time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
          $time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
         
  $diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
          if($day1 > $day2) {
              $diff -= 1;
          } elseif($day1 == $day2) {
              if($time1 > $time2) {
                  $diff -= 1;
              }
          }
          break;
      case "w":
          // Only simple seconds calculation needed from here on
          $diff = floor($seconds / 604800);
          break;
      case "d":
          $diff = floor($seconds / 86400);
          break;
      case "h":
          $diff = floor($seconds / 3600);
          break;      
      case "i":
          $diff = floor($seconds / 60);
          break;      
      case "s":
          $diff = $seconds;
          break;      
  }
  //return the +ve integer only
  if ($diff<0){
     $diff=0-$diff;
  }
  return $diff;
}
echo "x: $dateA
";
echo "y: $dateB
";
echo "
";
echo datediff ("d",$dateA, $dateB);


cepercival

Hopefully this may be useful to someone out there!
I wanted a simple function to give me a duration for phone calls using a start timestamp and end timestamp. After finding an understandable example here http://www.brenlei.com/articles/php/dates/dates4.php i cobbled this together:
function callDuration($dateTimeBegin,$dateTimeEnd) {
     
     $dif=$dateTimeEnd - $dateTimeBegin;
     $hours = floor($dif / 3600);
     $temp_remainder = $dif - ($hours * 3600);

     $minutes = floor($temp_remainder / 60);
     $temp_remainder = $temp_remainder - ($minutes * 60);

     $seconds = $temp_remainder;
     
     // leading zero's - not bothered about hours
     $min_lead=':';
    if($minutes <=9)
       $min_lead .= '0';
     $sec_lead=':';
    if($seconds <=9)
       $sec_lead .= '0';

 // difference/duration returned as Hours:Mins:Secs e.g. 01:29:32
 return $hours.$min_lead.$minutes.$sec_lead.$seconds;

      }
obviously it can be easily extended to include days, weeks etc.
Stupidly simple I know but that's how i like it.


cupidomind

Hi I just want to say thanks a lot to the man who wrote a solution about a problem of the date-difference.
/*A much easier way to do days diff is to use Julian Days from the Calendar functions:
$start = gregoriantojd($smon, $sday, $syear);
$end = gregoriantojd($emon, $eday, $eyear);
$daysdiff = $end - $start;
You can see the obvious ways to wrap a function around that.*/


gary

here's a quick script i used to find recurring dates, it offers some flexibility in how you want to iterate though the dates
<?php
// ----------------------------------------------------------
//  Recurring dates
//  Returns an array of recurring dates
// ----------------------------------------------------------
class recur {

var $endOption; // set to either "endBy" or "endAfter" -- endby if you want to end by a date and
// end after if you want to end after 'x' amount of occurrences
var $endValue;      // set to either a date in 'xxxx-xx-xx' format or a number of occurrences
var $start; // set to the starting date in 'xxxx-xx-xx' format

function interval($type, $spread){
$startDate = explode("-", $this->start);
$time = mktime(0, 0, 0, $startDate[1], $startDate[2], $startDate[0]);

$dates[] = $this->start;

if($this->endOption == "endAfter"){

for($i = 1; $i < $this->endValue; $i++){
$futureTime = strtotime("+$spread $type", $time);
$dates[] = date("Y-m-d", $futureTime);
$time = $futureTime;
}

return $dates;
}else if($this->endOption == "endBy"){
$endDate = explode("-", $this->endValue);
$endTime = mktime(0, 0, 0, $endDate[1], $endDate[2], $endDate[0]);

while($endTime > $time){
$futureTime = strtotime("+$spread $type", $time);
if($futureTime > $endTime){
break;
}
$dates[] = date("Y-m-d", $futureTime);
$time = $futureTime;
}
return $dates;
}
}

}
?>
example:
<?php
include("includes/recur.class.php");
$recur = new recur();
$recur->endOption = "endBy";
$recur->endValue = '2006-12-09';
$recur->start = '2006-04-28';
print_r($recur->interval("day", 4));
?>


visualmind

Here's a new function for Hejri (Hijri) date conversion, It has a better flawless calculation than the previous posted function and it's implemented to be an official alternative for the php DATE function which returns Arabic Translated date and optionally Hejri converted.
Note: to view arabic titles correctly change view-encoding to Arabic-Windows (windows-1256)
function arabicDate($format, $timestamp) {
/*
  written by Salah Faya (visualmind@php.net) http://www.php4arab.info/scripts/arabicDate
$format:
  [*]hj|ar|en:[jdl][Fmn][Yy][Aa]  (php.date function handles the rest chars)
  * will add <span dir=rtl lang=ar-sa>..</span>
  examples:
  echo arabicDate('hj:l d-F-Y åÜ', time());  
  echo arabicDate('ar:l d/F - h:iA', time());
*/
$format=trim($format);
if (substr($format,0,1)=='*') {
               $use_span=true;
$format=substr($format,1);
       } else $use_span=false;
$type=substr($format,0,3);
$arDay = array("Sat"=>"ÇáÓÈÊ", "Sun"=>"ÇáÃÍÏ", "Mon"=>"ÇáÅËäíä", "Tue"=>"ÇáËáÇËÇÁ",
"Wed"=>"ÇáÃÑÈÚÇÁ", "Thu"=>"ÇáÎãíÓ", "Fri"=>"ÇáÌãÚÉ");
$ampm=array('am'=>'ÕÈÇÍÇ','pm'=>'ãÓÇÁ');
list($d,$m,$y,$dayname,$monthname,$am)=explode(' ',date('d m Y D M a', $timestamp));
if ($type=='hj:') {
if (($y>1582)||(($y==1582)&&($m>10))||(($y==1582)&&($m==10)&&($d>14))) {
$jd=ard_int((1461*($y+4800+ard_int(($m-14)/12)))/4);
$jd+=ard_int((367*($m-2-12*(ard_int(($m-14)/12))))/12);
$jd-=ard_int((3*(ard_int(($y+4900+ard_int(($m-14)/12))/100)))/4);
$jd+=$d-32075;
} else {
$jd = 367*$y-ard_int((7*($y+5001 + ard_int(($m-9)/7)))/4) + ard_int((275*$m)/9)+$d+1729777;
}
$l=$jd-1948440+10632;
$n=ard_int(($l-1)/10631);
$l=$l-10631*$n+355;  // Correction: 355 instead of 354
$j=(ard_int((10985-$l)/5316)) * (ard_int((50*$l)/17719)) + (ard_int($l/5670)) * (ard_int((43*$l)/15238));
$l=$l-(ard_int((30-$j)/15)) * (ard_int((17719*$j)/50)) - (ard_int($j/16)) * (ard_int((15238*$j)/43))+29;
$m=ard_int((24*$l)/709);
$d=$l-ard_int((709*$m)/24);
$y=30*$n+$j-30;
$format=substr($format,3);
$hjMonth = array("ãÍÑã", "ÕÝÑ", "ÑÈíÚ Ãæá", "ÑÈíÚ ËÇäí",
"ÌãÇÏ Ãæá", "ÌãÇÏ ËÇäí", "ÑÌÈ", "ÔÚÈÇä", "ÑãÖÇä", "ÔæÇá", "Ðæ ÇáÞÚÏÉ", "Ðæ ÇáÍÌÉ");
$format=str_replace('j', $d, $format);
$format=str_replace('d', str_pad($d,2,0,STR_PAD_LEFT), $format);
$format=str_replace('l', $arDay[$dayname], $format);
$format=str_replace('F', $hjMonth[$m-1], $format);
$format=str_replace('m', str_pad($m,2,0,STR_PAD_LEFT), $format);
$format=str_replace('n', $m, $format);
$format=str_replace('Y', $y, $format);
$format=str_replace('y', substr($y,2), $format);
$format=str_replace('a', substr($ampm[$am],0,1), $format);
$format=str_replace('A', $ampm[$am], $format);
} elseif ($type=='ar:') {
$format=substr($format,3);
$arMonth=array("Jan"=>"íäÇíÑ", "Feb"=>"ÝÈÑÇíÑ","Mar"=>"ãÇÑÓ", "Apr"=>"ÇÈÑíá", "May"=>"ãÇíæ",
"Jun"=>"íæäíæ", "Jul"=>"íæáíæ", "Aug"=>"ÇÛÓØÓ", "Sep"=>"ÓÈÊãÈÑ", "Oct"=>"ÇßÊæÈÑ",
"Nov"=>"äæÝãÈÑ", "Dec"=>"ÏíÓãÈÑ");
$format=str_replace('l', $arDay[$dayname], $format);
$format=str_replace('F', $arMonth[$monthname], $format);
$format=str_replace('a', substr($ampm[$am],0,1), $format);
$format=str_replace('A', $ampm[$am], $format);
       }
$date = date($format, $timestamp);
if ($use_span) return '<span dir="rtl" lang="ar-sa">'.$date.'</span>';
else return $date;
}
function ard_int($float) {
      return ($float < -0.0000001) ? ceil($float-0.0000001) : floor($float+0.0000001);
}


leopoldo a dot oducado poducado

Here is my function to count the number days, weeks, months, and year. I tried it below 1970 and it works.
<?php
function datecal($date,$return_value)
{
$date = explode("/", $date);
$month_begin = $date[0];
$month_begin_date = $date[1];
$year1 = $date[2];
$month_end = date("n");
$month_end_date = date("j");
$year2 = date("Y");
$days_old = 0;
$years_old = 0;
$months_old = 0;
if($month_begin==12)
{
 $month = 1;
 $year = $year1+1;
}
else
{
 $month = $month_begin+1;
 $year = $year1;
}
$begin_plus_days = cal_days_in_month(CAL_GREGORIAN, $month_begin, $year1) - $month_begin_date;
$end_minus_days = cal_days_in_month(CAL_GREGORIAN, $month_end, $year2) - $month_end_date;
while ($year <= $year2)
{
if($year == $year2)
{
 $days_old = $days_old + cal_days_in_month(CAL_GREGORIAN, $month, $year);
 if($month < $month_end)
   {
    $months_old = $months_old + 1;    
    $month = $month + 1;
   }
         elseif ($month==$month_end and $month_end_date >= $month_begin_date)
           {
    $year = $year2+1;
   }
 else
   {
    $year = $year2+1;
   }
}
else
{
$days_old = $days_old + cal_days_in_month(CAL_GREGORIAN, $month, $year);
        if ($month <= 11)
           {
    $month = $month + 1;
    $months_old = $months_old + 1;
           }
        else
           {
    $month = 1;
    $year = $year + 1;
    $months_old = $months_old + 1;
           }
}
}
$days_old = ($days_old + $begin_plus_days) - $end_minus_days;
if($return_value == "d")
 { return $days_old; }
elseif ($return_value == "w")
 { return intval($days_old/7); }
elseif ($return_value == "m")
 { return $months_old; }
elseif ($return_value == "y")
 { return intval($months_old/12); }
}
echo datecal("08/13/1975","m");
?>


jeff

Here is a somewhat simpler function for getting the number of  business days between two dates
<?php
function WorkDays( $startTime, $endTime )
{
$workdays = 0 ;
while( $startTime <= $endTime )
{
if( date('w', $startTime ) != 6 && date( 'w', $startTime) != 0 )
{
$workdays++ ;
}
$startTime += 86400 ;
}
return $workdays ;
}
?>


scott_webster_2000

Here is a slight improvement over wwb_99@yahoo's entry.  (It works now.)
function date_diff($earlierDate, $laterDate) {
 //returns an array of numeric values representing days, hours, minutes & seconds respectively
 $ret=array('days'=>0,'hours'=>0,'minutes'=>0,'seconds'=>0);
 $totalsec = $laterDate - $earlierDate;
 if ($totalsec >= 86400) {
   $ret['days'] = floor($totalsec/86400);
   $totalsec = $totalsec % 86400;
 }
 if ($totalsec >= 3600) {
   $ret['hours'] = floor($totalsec/3600);
   $totalsec = $totalsec % 3600;
 }
 if ($totalsec >= 60) {
   $ret['minutes'] = floor($totalsec/60);
 }
 $ret['seconds'] = $totalsec % 60;
 return $ret;
}


eric

Here is a quick example of how to iterate through all days
between 2 dates (with a adjustable increment)
---------------------------------------------------------
//make time stamps from our start & end dates
$start_time = mktime(0,0,0,$start_month,$start_day,$start_year);
$end_time = mktime(0,0,0,$end_month,$end_day,$end_year);
//find the number of days between start_time & end_time
$days = ($end_time - $start_time) / (24 * 3600);
//we want to count the days including the first ..
$days++;
//select a 1 week interval ..
$inc=7;  
//find all days (actually periods since we use a increment)
for ($i=0;$i<$days;$i+=$inc)
{
 //calculate start & end of period using some magic of mktime :)
 $start_date = date("Y-m-d", mktime(0,0,0,$start_month,$start_day+$i,$start_year));
 $end_date = date("Y-m-d", mktime(0,0,0,$start_month,$start_day+$i+$inc-1,$start_year));  
 //print it all ...
 print("Period start:" . $start_date . "\n");
 print("Period end: " . $end_date . "\n");
}


wwb_99

Handy little function getting the total difference in dates.
function DateDiff($tfirst, $tsecond)
{
   //returns an array with numeric values for in an array measuring days, hours, minutes & seconds
   $ret=array();
   $totalsec=$tsecond-$tfirst;
   $ret['days']=round(($totalsec/86400));
   $totalsec=$totalsec % 86400;
   $ret['hours']=round(($totalsec/3600));
   $totalsec=$totalsec % 3600;
   $ret['minutes']=round(($totalsec/60));
   $ret['seconds']=$totalsec % 60;
   return $ret;
}


r00t_

Function generate one month calendar like
February
Mon Tue Wed Thu Fri Sat Sun
              1  2   3   4
  5   6   7     8   9    10  11
12  13   14   15   16  17 18
19  20   21   22   23  24 25
26  27   28
(default in russian locale)
<?php
$year = (int)$_GET["year"];
$month = (int)$_GET["month"];
draw_month_cal($year, $month);
function draw_month_cal($year, $month, $locale = array ('ru_RU.CP1251', 'rus_RUS.1251'))
{
   if (checkdate($month, 1, $year) && setlocale (LC_TIME, $locale)) {

       if (!$day = date("w", $f_day = mktime(0, 0, 0, $month, 1, $year)))
$day = 7; // Mon first, Sun last
       
       print "<table border=0><tr><th colspan=7>" . strftime("%B", $f_day) . "</td></tr><tr>"; // Month
       
       for ($i = 8; --$i;)
print "<th>" . strftime("%a", mktime(0, 0, 0, $month, 16 - $i - $day, $year)) . "</th>"; // Mon Tue Wed Thu Fri Sat Sun  

       print "</tr><tr>" . str_repeat("<td></td>", --$day); // Empty cells

       while (checkdate($month, ++$i, $year)) { // $i==0 after for :-)
           print "<td>$i</td>";
           if (!(++$day % 7)) print "</tr><tr>"; // next line after Sun
       }
       print "</tr></table>";
   }
}
?>


rycker+phpdate

Function for converting MySQL timestamp to Datetime format
function TimestampToDatetime($Tstamp) {
$dt[0] = substr($Tstamp,0,4);
$dt[1] = substr($Tstamp,4,2);
$dt[2] = substr($Tstamp,6,2);
$tm[0] = substr($Tstamp,8,2);
$tm[1] = substr($Tstamp,10,2);
$tm[2] = substr($Tstamp,12,2);
return (join($dt,"-") . " " . join($tm,":"));
}


worm zantatglazovdotnet

Function for converting  RFC 2822 formatted date to timestamp
<?php
/**
* @param  string  $date RFC 2822 formatted date
* @return integer timestamp
*/
function Rfc2822ToTimestamp($date){
 $aMonth = array(
             "Jan"=>"1", "Feb"=>"2", "Mar"=>"3", "Apr"=>"4", "May"=>"5",
             "Jun"=>"6", "Jul"=>"7", "Aug"=>"8", "Sep"=>"9", "Oct"=>"10",
             "Nov"=>"11", "Dec"=>"12");
 list( , $day, $month, $year, $time) = explode(" ", $date);
 list($hour, $min, $sec) = explode(":", $time);
 $month = $aMonth[$month];
 return mktime($hour, $min, $sec, $month, $day, $year);
}
?>


gnrfan

function date_diff_as_text($ts1, $ts2) {
 /*
 $ts1 = "2007-01-05 10:30:45";
 $ts2 = "2007-01-06 10:31:46";
 echo date_diff_as_text($ts1, $ts2);
 */
 $ts1 = strtotime($ts1);
 $ts2 = strtotime($ts2);
 $diff = abs($ts1-$ts2);
 $sec_min = 60;
 $sec_hour = $sec_min*60;
 $sec_dias = $sec_hour*24;
 $dias = intval($diff/$sec_dias);
 $hours = intval($diff/$sec_hour)%24;
 $minutes = intval($diff/$sec_min)%60;
 $seconds = $diff%60;
 if ($dias > 0) {
   $result = "$days day";
   if ($dias > 1) {
     $result .= "s";
   }
 }
 if ($hours > 0) {
   $result .= " $hours hour";
   if ($hours > 1) {
     $result .= "s";
   }
 }
 if ($minutes > 0) {
   $result .= " $minutes minute";
   if ($minutes > 1) {
     $result .= "s";
   }
 }
 if ($seconds > 0) {
   $result .= " $seconds second";
   if ($seconds > 1) {
     $result .= "s";
   }
 }
 $result = explode(" ", $result);
 if (count($result)>2) {
   end($result);
   $key1 = key($result);
   prev($result);
   $key2 = key($result);
   $aux = $result[$key2];
   $aux .= " ".$result[$key1];
   unset($result[$key1]);
   unset($result[$key2]);
   $result = implode(" ", $result);
   $result .= " y $aux";
 } else {
   $result = implode(" ", $result);
 }
 return $result;
}


mail

For those who are using pre MYSQL 4.1.1, you can use:
TO_DAYS([Date Value 1])-TO_DAYS([Date Value 2])
For the same result as:
DATEDIFF([Date Value 1],[Date Value 2])


jlim

For a date() function that supports dates outside the range 1901 and 2038 (by using floats when needed) see adodb_date( ) in
http://php.weblogs.com/adodb_date_time_library


you nospam don't need 2 know etc

EXCEL DATES TO UNIX TIMESTAMPS
----------------------------
I get a lot of dates which are sent to me in those dastardly Excel spreadsheet things. For example, the date 15 April 1976, Excel stores as 27865.
I convert these to UNIX timestamps using the little function below.
<?
function xl2timestamp($xl_date)
{
$timestamp = ($xl - 25569) * 86400;
return $timestamp;
}
?>


h3

EXCEL DATES TO UNIX TIMESTAMPS 2.0
----------------------------
In reply of the comment left on 24-Mar-2003 10:17
The function is broken, and they output date was alwasy offset of 1 day. I think it is caused by a leap year bug in excel. Here is a fixed version, now the date match exactly what they should match.
function xl2timestamp($timestamp) {
return ($timestamp - 25568) * 86400;
}
eg;
echo date('Y-m-d',xl2timestamp(38976));
I found the infos on this bug in;
http://tinyurl.com/28lltv
cheers.


glashio

Calculate Sum BusinessDays (Mon till Fri) between two date's :
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
elseif ($adate['wday'] == 6) // Saterday
$date += $begindate ? $day * 2 : -$day;
return $date;
}
?>


mincklerstraat

Before you get too advanced using date functions, be sure also to see the calendar functions at http://www.php.net/manual/en/ref.calendar.php .

mikeb

Another month late on this, but I would amend alex's post to recommend using gmdate() any time you're trying to represent a "delta time", or your local timezone is likely to interfere.
For example, a five minute difference (300 seconds) would appear as follows in New York:
echo date('z:H:i:s', 300);
// 364:19:05:00
echo gmdate('z:H:i:s', 300);
// 0:00:05:00
Thanks for the 'z', though, Alex.  Up until now, I've always been dividing that out -- hadn't found it in the format list.  :-)


zan

an update to my earlier webcalendar funciton this is a class that uses a table full of start and end dates to generate a webcalendar http://www.stargeek.com/scripts.php?script=11&cat=blog

php

Additional thisone here (didn't test it yet but should work :D):
<?php
/**
* Calculates the Difference between two timestamps
*
* @param integer $start_timestamp
* @param integer $end_timestamp
* @param integer $unit (default 0)
* @return string
* @access public
*/
function dateDifference($start_timestamp,$end_timestamp,$unit= 0){
 $days_seconds_star= (23 * 56 * 60) + 4.091; // Star Day
 $days_seconds_sun= 24 * 60 * 60; // Sun Day
 $difference_seconds= $end_timestamp - $start_timestamp;
 switch($unit){
   case 3: // Days
     $difference_days= round(($difference_seconds / $days_seconds_sun),2);
     return 'approx. '.$difference_hours.' Days';
   case 2: // Hours
     $difference_hours= round(($difference_seconds / 3600),2);
     return 'approx. '.$difference_hours.' Hours';
   break;
   case 1: // Minutes
     $difference_minutes= round(($difference_seconds / 60),2);
     return 'approx. '.$difference_minutes.' Minutes';
   break;
   default: // Seconds
     if($difference_seconds > 1){
       return $difference_seconds.' Seconds';
     }
     else{
       return $difference_seconds.' Second';
     }
 }
}
?>


info

A simple DateAdd() function:
function DateAdd($v,$d=null , $f="d/m/Y"){
 $d=($d?$d:date("Y-m-d"));
 return date($f,strtotime($v." days",strtotime($d)));
}
Then use it:
echo DateAdd(2);  // 2 days after
echo DateAdd(-2,0,"Y-m-d");  // 2 days before with gigen format
echo DateAdd(3,"01/01/2000");  // 3 days after given date


vincentv

A rectification to the some of the functions i posted a while ago.
They do not work correctly under all circumstances (in my small test cases they worked) which is due to the fact that when you create a date using mktime, which returns a certain amount of seconds, this is not valid for every month since each month has a different amount of seconds.
The solution is to break up the original timestamp, add to it's seperate parts and create a new timestamp.
Old:
=====
function sub($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
   $mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
   return $timestamp - $mytime;
}
function add($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
   $mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
   return $timestamp + $mytime;
}
=====
New:
=====
function add($timestamp, $seconds, $minutes, $hours, $days, $months, $years) {
$timePieces = getdate($timestamp);
return mktime( $timePieces["hours"] + $hours,
$timePieces["minutes"] + $minutes,
$timePieces["seconds"] + $seconds,
$timePieces["mon"] + $months,
$timePieces["mday"] + $days,
$timePieces["year"] + $years );
}
function sub($timestamp, $seconds, $minutes, $hours, $days, $months, $years) {
$timePieces = getdate($timestamp);
return mktime( $timePieces["hours"] - $hours,
$timePieces["minutes"] - $minutes,
$timePieces["seconds"] - $seconds,
$timePieces["mon"] - $months,
$timePieces["mday"] - $days,
$timePieces["year"] - $years );
}
=====
Regards,
- Vincent


03-mar-2006 03:50

A quick one liner to round a timestamp to the next full hour.
ie, 8:36 => 9:00, 9:02 => 10:00
$timestamp = ceil(time()/3600)*3600;


chad 0x40 herballure 0x2e com

A number of functions, all of which use the OO interface to the new DateTime classes, are documented as having been available since PHP 5.1. This is not entirely true; although they exist in the PHP 5.1 sources, they're protected by '#ifdef EXPERIMENTAL_DATE_SUPPORT' blocks. Therefore, they aren't really available in those releases without extreme measures.
The new datetime support did not officially arrive until the 5.2 series.


php

A much easier way to do days diff is to use Julian Days from the Calendar functions:
$start = gregoriantojd($smon, $sday, $syear);
$end = gregoriantojd($emon, $eday, $eyear);
$daysdiff = $end - $start;
You can see the obvious ways to wrap a function around that.


alex dot stevenson

A few months late on this, but I just saw cepercival at thatMailThatsHot dot com 's post, and think that it may be a bit easier to just use this as opposed to writing it by hand:
date("z:H:i:s", $endTimestamp - $startTimestamp);
Since the timestamps store seconds from the unix epoch, and the unix epoch occured at the very beginning of a year, you can get away with this.
It gets a little trickier to place the years, but it should work fine if you subtract out the number of years date("Y", 0) returns.  This would naturally require two seperate calls to the date function- one to find the year, and one to find the rest of the information.


stoicnluv

A better and accurate function to calculate the difference between 2 dates. Takes leap years and DST into consideration. Accepts string date or timestamp as arguments.
<?php
function date_diff($d1, $d2){
$d1 = (is_string($d1) ? strtotime($d1) : $d1);
$d2 = (is_string($d2) ? strtotime($d2) : $d2);
$diff_secs = abs($d1 - $d2);
$base_year = min(date("Y", $d1), date("Y", $d2));
$diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);
return array(
"years" => date("Y", $diff) - $base_year,
"months_total" => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
"months" => date("n", $diff) - 1,
"days_total" => floor($diff_secs / (3600 * 24)),
"days" => date("j", $diff) - 1,
"hours_total" => floor($diff_secs / 3600),
"hours" => date("G", $diff),
"minutes_total" => floor($diff_secs / 60),
"minutes" => (int) date("i", $diff),
"seconds_total" => $diff_secs,
"seconds" => (int) date("s", $diff)
);
}
$a = date_diff("2006-11-01", "2007-11-01");
echo "<pre>";
print_r($a);
echo "</pre>";
?>
This example will output (if your timezone uses US DST):
Array
(
   [years] => 0
   [months_total] => 11
   [months] => 11
   [days_total] => 364
   [days] => 30
   [hours_total] => 8759
   [hours] => 23
   [minutes_total] => 525540
   [minutes] => 0
   [seconds_total] => 31532400
   [seconds] => 0
)
As you can see, the result is not exactly 1 year (less 1 hour) since Nov 1, 2006 is not DST while Nov 1, 2007 is DST.


andreencinas

//function like dateDiff Microsoft
      //not error in year Bissesto
      function dateDiff($interval,$dateTimeBegin,$dateTimeEnd) {
        //Parse about any English textual datetime
        //$dateTimeBegin, $dateTimeEnd
        $dateTimeBegin=strtotime($dateTimeBegin);
        if($dateTimeBegin === -1) {
          return("..begin date Invalid");
        }
        $dateTimeEnd=strtotime($dateTimeEnd);
        if($dateTimeEnd === -1) {
          return("..end date Invalid");
        }
        $dif=$dateTimeEnd - $dateTimeBegin;
        switch($interval) {
          case "s"://seconds
              return($dif);
          case "n"://minutes
              return(floor($dif/60)); //60s=1m
          case "h"://hours
              return(floor($dif/3600)); //3600s=1h
          case "d"://days
              return(floor($dif/86400)); //86400s=1d
          case "ww"://Week
              return(floor($dif/604800)); //604800s=1week=1semana
          case "m": //similar result "m" dateDiff Microsoft
              $monthBegin=(date("Y",$dateTimeBegin)*12)+
                date("n",$dateTimeBegin);
              $monthEnd=(date("Y",$dateTimeEnd)*12)+
                date("n",$dateTimeEnd);
              $monthDiff=$monthEnd-$monthBegin;
              return($monthDiff);
          case "yyyy": //similar result "yyyy" dateDiff Microsoft
              return(date("Y",$dateTimeEnd) - date("Y",$dateTimeBegin));
          default:
              return(floor($dif/86400)); //86400s=1d
        }
      }


owolawi

#=========================================
# a function to subtract from or add  seconds or minutes or hours or days or months or weeks or years to a specified date and return the updated date
#=========================================
#$newdate = dateadd("d",3,"2006-12-12"); #  add 3 days to date
#$newdate = dateadd("s",3,"2006-12-12"); #  add 3 seconds to date
#$newdate = dateadd("m",3,"2006-12-12"); #  add 3 minutes to date
#$newdate = dateadd("h",3,"2006-12-12"); #  add 3 hours to date
#$newdate = dateadd("ww",3,"2006-12-12"); #  add 3 weeks days to date
#$newdate = dateadd("m",3,"2006-12-12"); #  add 3 months to date
#$newdate = dateadd("yyyy",3,"2006-12-12"); #  add 3 years to date
#$newdate = dateadd("d",-3,"2006-12-12"); #  subtract 3 days from date
function dateAdd($interval,$number,$dateTime) {

$dateTime = (strtotime($dateTime) != -1) ? strtotime($dateTime) : $dateTime;  
$dateTimeArr=getdate($dateTime);

$yr=$dateTimeArr[year];
$mon=$dateTimeArr[mon];
$day=$dateTimeArr[mday];
$hr=$dateTimeArr[hours];
$min=$dateTimeArr[minutes];
$sec=$dateTimeArr[seconds];
switch($interval) {
case "s"://seconds
$sec += $number;
break;
case "n"://minutes
$min += $number;
break;
case "h"://hours
$hr += $number;
break;
case "d"://days
$day += $number;
break;
case "ww"://Week
$day += ($number * 7);
break;
case "m": //similar result "m" dateDiff Microsoft
$mon += $number;
break;
case "yyyy": //similar result "yyyy" dateDiff Microsoft
$yr += $number;
break;
default:
$day += $number;
        }  

$dateTime = mktime($hr,$min,$sec,$mon,$day,$yr);
$dateTimeArr=getdate($dateTime);

$nosecmin = 0;
$min=$dateTimeArr[minutes];
$sec=$dateTimeArr[seconds];
if ($hr==0){$nosecmin += 1;}
if ($min==0){$nosecmin += 1;}
if ($sec==0){$nosecmin += 1;}

if ($nosecmin>2){ return(date("Y-m-d",$dateTime));} else { return(date("Y-m-d G:i:s",$dateTime));}
}


Change Language


Follow Navioo On Twitter
.NET Functions
Apache-specific Functions
Alternative PHP Cache
Advanced PHP debugger
Array Functions
Aspell functions [deprecated]
BBCode Functions
BCMath Arbitrary Precision Mathematics Functions
PHP bytecode Compiler
Bzip2 Compression Functions
Calendar Functions
CCVS API Functions [deprecated]
Class/Object Functions
Classkit Functions
ClibPDF Functions [deprecated]
COM and .Net (Windows)
Crack Functions
Character Type Functions
CURL
Cybercash Payment Functions
Credit Mutuel CyberMUT functions
Cyrus IMAP administration Functions
Date and Time Functions
DB++ Functions
Database (dbm-style) Abstraction Layer Functions
dBase Functions
DBM Functions [deprecated]
dbx Functions
Direct IO Functions
Directory Functions
DOM Functions
DOM XML Functions
enchant Functions
Error Handling and Logging Functions
Exif Functions
Expect Functions
File Alteration Monitor Functions
Forms Data Format Functions
Fileinfo Functions
filePro Functions
Filesystem Functions
Filter Functions
Firebird/InterBase Functions
Firebird/Interbase Functions (PDO_FIREBIRD)
FriBiDi Functions
FrontBase Functions
FTP Functions
Function Handling Functions
GeoIP Functions
Gettext Functions
GMP Functions
gnupg Functions
Net_Gopher
Haru PDF Functions
hash Functions
HTTP
Hyperwave Functions
Hyperwave API Functions
i18n Functions
IBM Functions (PDO_IBM)
IBM DB2
iconv Functions
ID3 Functions
IIS Administration Functions
Image Functions
Imagick Image Library
IMAP
Informix Functions
Informix Functions (PDO_INFORMIX)
Ingres II Functions
IRC Gateway Functions
PHP / Java Integration
JSON Functions
KADM5
LDAP Functions
libxml Functions
Lotus Notes Functions
LZF Functions
Mail Functions
Mailparse Functions
Mathematical Functions
MaxDB PHP Extension
MCAL Functions
Mcrypt Encryption Functions
MCVE (Monetra) Payment Functions
Memcache Functions
Mhash Functions
Mimetype Functions
Ming functions for Flash
Miscellaneous Functions
mnoGoSearch Functions
Microsoft SQL Server Functions
Microsoft SQL Server and Sybase Functions (PDO_DBLIB)
Mohawk Software Session Handler Functions
mSQL Functions
Multibyte String Functions
muscat Functions
MySQL Functions
MySQL Functions (PDO_MYSQL)
MySQL Improved Extension
Ncurses Terminal Screen Control Functions
Network Functions
Newt Functions
NSAPI-specific Functions
Object Aggregation/Composition Functions
Object property and method call overloading
Oracle Functions
ODBC Functions (Unified)
ODBC and DB2 Functions (PDO_ODBC)
oggvorbis
OpenAL Audio Bindings
OpenSSL Functions
Oracle Functions [deprecated]
Oracle Functions (PDO_OCI)
Output Control Functions
Ovrimos SQL Functions
Paradox File Access
Parsekit Functions
Process Control Functions
Regular Expression Functions (Perl-Compatible)
PDF Functions
PDO Functions
Phar archive stream and classes
PHP Options&Information
POSIX Functions
Regular Expression Functions (POSIX Extended)
PostgreSQL Functions
PostgreSQL Functions (PDO_PGSQL)
Printer Functions
Program Execution Functions
PostScript document creation
Pspell Functions
qtdom Functions
Radius
Rar Functions
GNU Readline
GNU Recode Functions
RPM Header Reading Functions
runkit Functions
SAM - Simple Asynchronous Messaging
Satellite CORBA client extension [deprecated]
SCA Functions
SDO Functions
SDO XML Data Access Service Functions
SDO Relational Data Access Service Functions
Semaphore
SESAM Database Functions
PostgreSQL Session Save Handler
Session Handling Functions
Shared Memory Functions
SimpleXML functions
SNMP Functions
SOAP Functions
Socket Functions
Standard PHP Library (SPL) Functions
SQLite Functions
SQLite Functions (PDO_SQLITE)
Secure Shell2 Functions
Statistics Functions
Stream Functions
String Functions
Subversion Functions
Shockwave Flash Functions
Swish Functions
Sybase Functions
TCP Wrappers Functions
Tidy Functions
Tokenizer Functions
Unicode Functions
URL Functions
Variable Handling Functions
Verisign Payflow Pro Functions
vpopmail Functions
W32api Functions
WDDX Functions
win32ps Functions
win32service Functions
xattr Functions
xdiff Functions
XML Parser Functions
XML-RPC Functions
XMLReader functions
XMLWriter Functions
XSL functions
XSLT Functions
YAZ Functions
YP/NIS Functions
Zip File Functions
Zlib Compression Functions
eXTReMe Tracker