PHP
PHP教程 | PHP论坛 | PHP中文手册

Search for

XXII. Date/Time 日期/时间函数

简介

可以用这些函数得到 PHP 所运行的服务器的日期和时间。可以用这些函数将日期和时间以很多不同方式格式化输出。

注意: 请留意这些函数依赖于服务器的地区设置。确认在使用这些函数时考虑到了夏令时的设置(例如使用 $date = strtotime('+7 days', $date) 而不是 $date += 7*24*60*60)和闰年。

注意: 该部份所提及的时区可参考附录 I, 所支持时区列表

需求

要编译本扩展模块无需外部库文件。

安装

本扩展模块作为 PHP 内核的一部分,无需安装即可使用。

运行时配置

本扩展模块在 php.ini 中未定义任何配置选项。

运行时配置

这些函数的行为受 php.ini 的影响。

表 37. 日期/时间配置选项

名称默认值可修改范围更新记录
date.default_latitude"31.7667"PHP_INI_ALL自 PHP 5.0.0 起可用
date.default_longitude"35.2333"PHP_INI_ALL自 PHP 5.0.0 起可用
date.sunrise_zenith"90.83"PHP_INI_ALL自 PHP 5.0.0 起可用
date.sunset_zenith"90.83"PHP_INI_ALL自 PHP 5.0.0 起可用
date.timezone""PHP_INI_ALL自 PHP 5.0.0 起可用

有关 PHP_INI_* 常量进一步的细节与定义参见附录 H, php.ini 配置选项

以下是配置选项的简要解释。

date.default_latitude float

默认纬度。

date.default_longitude float

默认经度。

date.sunrise_zenith float

默认日出天顶。

date.sunset_zenith float

默认日落天顶。

date.timezone string

在未设定 TZ 环境变量时用于所有日期/时间函数的默认时区。优先顺序在 date_default_timezone_get() 页面中有说明。

注意: 前四个配置选项目前仅用于 date_sunrise()date_sunset()

资源类型

本扩展模块未定义任何资源类型。

预定义常量

自 PHP 5.1.1 起定义有以下常量来提供标准日期表达方法,可以用于日期格式函数(例如 date())。

DATE_ATOMstring
原子钟格式(如:2005-08-15T15:52:01+00:00)
DATE_COOKIEstring
HTTP Cookies 格式(如:Mon, 15 Aug 2005 15:52:01 UTC)
DATE_ISO8601string
ISO-8601(如:2005-08-15T15:52:01+0000)
DATE_RFC822string
RFC 822(如:Mon, 15 Aug 2005 15:52:01 UTC)
DATE_RFC850string
RFC 850(如:Monday, 15-Aug-05 15:52:01 UTC)
DATE_RFC1036string
RFC 1036(如:Monday, 15-Aug-05 15:52:01 UTC)
DATE_RFC1123string
RFC 1123(如:Mon, 15 Aug 2005 15:52:01 UTC)
DATE_RFC2822string
RFC 2822(如:Mon, 15 Aug 2005 15:52:01 +0000)
DATE_RSSstring
RSS(如:Mon, 15 Aug 2005 15:52:01 UTC)
DATE_W3Cstring
World Wide Web Consortium(如:2005-08-15T15:52:01+00:00)

目录

checkdate — 验证一个格里高里日期
date_create — Returns new DateTime object
date_date_set — Sets the date
date_default_timezone_get — 取得一个脚本中所有日期时间函数所使用的默认时区
date_default_timezone_set — 设定用于一个脚本中所有日期时间函数的默认时区
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 — 返回给定的日期与地点的日出时间
date_sunset — 返回给定的日期与地点的日落时间
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 — 格式化一个本地时间/日期
getdate — 取得日期/时间信息
gettimeofday — 取得当前时间
gmdate — 格式化一个 GMT/UTC 日期/时间
gmmktime — 取得 GMT 日期的 UNIX 时间戳
gmstrftime — 根据区域设置格式化 GMT/UTC 时间/日期
idate — 将本地时间日期格式化为整数
localtime — 取得本地时间
microtime — 返回当前 Unix 时间戳和微秒数
mktime — 取得一个日期的 Unix 时间戳
strftime — 根据区域设置格式化本地时间/日期
strptime — 解析由 strftime() 生成的日期/时间
strtotime — 将任何英文文本的日期时间描述解析为 Unix 时间戳
time — 返回当前的 Unix 时间戳
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


User Contributed Notes Date/Time 日期/时间函数
herbert DOT fischer ATT gEE mail DOT com
12-Oct-2007 04:44
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]
aquatakat at telus dot net
25-Sep-2007 04:25
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
*/

?>
Darren Edwards
06-Sep-2007 11:54
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.
carsten dot klein at abstraxion dot org
23-Aug-2007 05:15
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
carsten dot klein at abstraxion dot org
23-Aug-2007 06:02
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 ;-)
chad 0x40 herballure 0x2e com
25-May-2007 02:50
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.
wes9999 at myfastmail dot com
18-Apr-2007 11:33
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.
gnrfan at gnrfan dot org
04-Apr-2007 11:44
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;

}
Leopoldo A dot Oducado (poducado at comfsm dot fm)
16-Feb-2007 11:50
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");
?>
h3 at valleyfield dot net
31-Jan-2007 02:56
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.
owolawi at hotmail dot com
29-Jan-2007 07:02
#=========================================
# 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));}
}
bgold at matrix-consultants dot com
17-Jan-2007 09:08
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";
                }
        }
?>
slash at mauricien dot org
23-Dec-2006 05:06
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;
James
22-Dec-2006 05:20
info at flash-ultra dot de, you could just use UNIX_TIMESTAMP(DATE) in your SQL query.
info at flash-ultra dot de
18-Dec-2006 08:17
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]);
    }
mikeb at tracersinfo dot com
07-Nov-2006 03:27
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.  :-)
alex dot stevenson at t8design dot com
13-Sep-2006 12:50
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.
cepercival at thatMailThatsHot dot com
11-Jul-2006 08:31
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.
gary at gmartellino dot com
05-May-2006 01:35
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));
?>
rugby7s at gmail dot com
08-Mar-2006 11:00
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
}
03-Mar-2006 11: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;
worm (zantATglazovDOTnet)
25-Jan-2006 10:44
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);
}
?>
Jeff
03-Nov-2005 11:29
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 ;
}

?>
cupidomind at yahoo dot fr
15-Oct-2005 11:18
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.*/
rycker+phpdate at gmail dot com
05-Oct-2005 03:30
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,":"));
}
andreencinas at yahoo dot com dot br
28-Sep-2005 08:08
//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
         }

       }
glashio at xs4all dot nl
27-Sep-2005 03:46
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;
}
?>
Eric Z (ezsomething at hotmail)
01-Sep-2005 05:56
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;
    }
?>
daniel at globalnetstudios dot com
09-Jun-2005 02:49
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;
  }
?>
mail at completeideas dot com
07-Jun-2005 04:55
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])
r00t_ at mail dot ru
06-May-2005 03:33
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>";
    }
}

?>
info at programare dot org
06-May-2005 01:34
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
datavortex at gmail dot com
19-Mar-2005 07:19
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) {
   
# er