mktime

(PHP 3, PHP 4, PHP 5)

mktime -- 取得一个日期的 Unix 时间戳

说明

int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )

根据给出的参数返回 Unix 时间戳。时间戳是一个长整数,包含了从 Unix 纪元(January 1 1970 00:00:00 GMT)到给定时间的秒数。

参数可以从右向左省略,任何省略的参数会被设置成本地日期和时间的当前值。

参数

hour

小时数。

minute

分钟数。

second

秒数(一分钟之内)。

month

月份数。

day

天数。

year

年份数,可以是两位或四位数字,0-69 对应于 2000-2069,70-100 对应于 1970-2000。在如今系统中普遍把 time_t 作为一个 32 位有符号整数的情况下,year 的合法范围是 1901 到 2038 之间,不过此限制自 PHP 5.1.0 起已被克服了。

is_dst

本参数可以设为 1,表示正处于夏时制时间(DST),0 表示不是夏时制,或者 -1(默认值)表示不知道是否是夏时制。如果未知,PHP 会尝试自己搞明白。这可能产生不可预知(但并非不正确)的结果。如果 PHP 运行的系统中启用了 DST 或者 is_dst 设为 1,某些时间是无效的。例如 DST 自 2:00 生效,则所有处于 2:00 到 3:00 之间的时间都无效,mktime() 会返回一个未定义(通常为负)的值。某些系统(例如 Solaris 8)的 DST 在午夜生效,则 DST 生效当天的 0:30 会被计算为前一天的 23:30。

注: 自 PHP 5.1.0 起,本参数已被废弃。应该使用新的时区处理特性来替代。

返回值

mktime() 根据给出的参数返回 Unix 时间戳。如果参数非法(例如年,月,日都是零),本函数返回 FALSE(在 PHP 5.1 之前返回 -1)。

更新日志

版本说明
3.0.10加入了 is_dst 参数
5.1.0 is_dst 参数被废弃。出错时函数返回 FALSE 而不再是 -1

范例

例子 1. mktime() 例子

mktime() 在做日期计算和验证方面很有用,它会自动计算超出范围的输入的正确值。例如下面例子中每一行都会产生字符串 "Jan-01-1998"。

<?php
echo date("M-d-Y", mktime(0, 0, 0, 12, 32, 1997));
echo
date("M-d-Y", mktime(0, 0, 0, 13, 1, 1997));
echo
date("M-d-Y", mktime(0, 0, 0, 1, 1, 1998));
echo
date("M-d-Y", mktime(0, 0, 0, 1, 1, 98));
?>

例子 2. 下个月的最后一天

任何给定月份的最后一天都可以被表示为下个月的第 "0" 天,而不是 -1 天。下面两个例子都会产生字符串 "The last day in Feb 2000 is: 29"。

<?php
$lastday
= mktime(0, 0, 0, 3, 0, 2000);
echo
strftime("Last day in Feb 2000 is: %d", $lastday);
$lastday = mktime(0, 0, 0, 4, -31, 2000);
echo
strftime("Last day in Feb 2000 is: %d", $lastday);
?>

注释

注意

在 PHP 5.1.0 之前,在任何已知 Windows 版本以及一些其它系统下不支持负的时间戳。因此年份的有效范围限制为 1970 到 2038。


add a note add a note User Contributed Notes
nuntius
08-Jun-2006 01:25
Easy way to get last month.
...and anything else in the date you want. Just introduce the calculation into the mktime function (note the -1) when building from date().

  
//Current Date minus one month.
$dateMinusOneMonth = mktime(0, 0, 0, date("m")-1, date("d"),  date("Y"));
$lastmonth = date("M", $dateMinusOneMonth);
echo $lastmonth;

change $dateMinusOneMonth to the below to see it react to a year change (get Dec as last month from January)
    
$dateMinusOneMonth = mktime(0, 0, 0, 01-1, 01, 2006);
dswigger at yahoo dot com
03-Jun-2006 09:39
Thought I would share a bit.  Hope someone finds it useful.

// The logic was ported from javascript : http://webexhibits.org/daylightsaving/b.html
// If any date is between these two then:
//During DST, clocks are turned forward an hour, effectively moving an hour of daylight from the morning to the evening.
define('ZT_DST_US',            1);//United States dst
define('ZT_DST_EU',            2);//European Union dst
function ztcalhlp_getGMTDST(&$destStart,&$destEnd,$year,$dst_type=ZT_DST_EU)
{
   // USA
   if($dst_type == ZT_DST_US)
   {
       $dstTime=2;
       $AprilDate=(2+6 * $year - floor($year / 4) ) % 7 + 1;
       $OctoberDate=(31-(floor ($year * 5 / 4) + 1) % 7);
       $MarchDate=14 - (floor (1 + $year * 5 / 4) % 7);
       $NovemberDate=7 - (floor (1 + $year * 5 / 4) % 7);
      
       $dstMonth1=($year>2006)?3:4;
       $dstMonth2=($year>2006)?11:10;
       $dstDay1 =($year>2006)?$MarchDate:$AprilDate;
       $dstDay2 =($year>2006)?$NovemberDate:$OctoberDate;
      
       $destStart=mktime($dstTime,0,0,$dstMonth1,$dstDay1,$year);
       $destEnd=mktime($dstTime,0,0,$dstMonth2,$dstDay2,$year);
       return;       
   }
   // has to eu then..
   $dstTime=1;
   $MarchDateEU=(31-(floor ($year * 5 / 4) + 4) % 7);
   $OctoberDateEU=(31-(floor ($year * 5 / 4) + 1) % 7);
   $destStart=mktime($dstTime,0,0,3,$MarchDateEU,$year);
   $destEnd=mktime($dstTime,0,0,10,$OctoberDateEU,$year);
}
carlo dot tafuro at poste dot it
08-May-2006 07:40
Negative timestamps give problem also using linux as guest operating system inside WMvare with Windows host operating system.
Fabrizio (staff at bibivu dot com)
30-Jan-2006 02:29
here a function that will help to find the difference between two dates, and it will take into consideration the leaps years

this function will return an array with:

YEARS (years)
MONTHS (months)
DAYS (days)
HOURS (hours)
MINUTES (minutes)
SECONDS (seconds)

probably can be optimized, but for now does the work
--------------------------------------------------------
Una funzione che aiuta a trovare la differenze tra due date, prendendo in considerazione anche gli anni bisestili.
 
Questa funzione ritorna un array con:

ANNI (years)
MESI (months)
GIORNI (days)
ORE (hours)
MINUTI (minutes)
SECONDI (seconds)

probabilmente puo' essere ottimizzata, ma per ora funziona
----------------------------------------------------------

<?php
  
function bib_datediff($fromtime, $totime=''){
       if(
$totime=='')        $totime = time();
      
       if(
$fromtime>$totime){
          
$tmp = $totime;
          
$totime = $fromtime;
          
$fromtime = $tmp;
       }
      
      
$timediff = $totime-$fromtime;
      
//check for leap years in the middle
      
for($i=date('Y',$fromtime); $i<=date('Y',$totime); $i++){
           if (((
$i%4 == 0) && ($i%100 != 0)) || ($i%400 == 0)) {
              
$timediff -= 24*60*60;
           }
       }
      
$remain = $timediff;
      
$ret['years']    = intval($remain/(365*24*60*60));
      
$remain            = $remain%(365*24*60*60);
      
$ret['days']    = intval($remain/(24*60*60));
      
$remain            = $remain%(24*60*60);

      
$m[0]    = 31;        $m[1]    = 28;        $m[2]    = 31;        $m[3]    = 30;
      
$m[4]    = 31;        $m[5]    = 30;        $m[6]    = 31;        $m[7]    = 31;
      
$m[8]    = 30;        $m[9]    = 31;        $m[10]    = 30;        $m[11]    = 31;
      
//if leap year, february has 29 days
      
if (((date('Y',$totime)%4 == 0) && (date('Y',$totime)%100 != 0)) || (date('Y',$totime)%400 == 0)){

          
$m[1] = 29;
       }
      
$ret['months']        = 0;
       foreach(
$m as $value){
           if(
$ret['days']>$value){
              
$ret['months']++;
              
$ret['days'] -=$value;
           } else {
               break;
           }
       }
      
$ret['hours']    = intval($remain/(60*60));
      
$remain            = $remain%(60*60);
      
$ret['minutes']    = intval($remain/60);
      
$ret['seconds']    = $remain%60;
       return
$ret;
   }
?>
manhon824 at gmail dot com
21-Jan-2006 04:24
I read the above note and think up a simple way(just 10 lines) to find time difference in days, hrs, mins, secs!
In my way, we do not need to fix the format of time!

$starttime=time();
// the start time can change to =strtotime($endtime);
$endtime=strtotime($endtime);
//$endtime can be any format as well as it can be converted to secs

$timediff = $endtime-$starttime;
   $days=intval($timediff/86400);
   $remain=$timediff%86400;
   $hours=intval($remain/3600);
   $remain=$remain%3600;
   $mins=intval($remain/60);
   $secs=$remain%60;

//this code is copied from the other note!thx to that guy!

$timediff=$days.'days'.$hours.'hr'.$mins.'min'.$secs.'s';

Hope that it is usefull!
McDonk2k at hotmail dot com
16-Jan-2006 06:19
I found this the other night and found it needed a couple tweeks to work. I few values were switched but now it works. This function finds the amount of days, hours, and minutes between two different dates/times. Thanks Tone.

<?php
function unix_diff($first_date,$first_time,$second_date,$second_time)
{

  
// Author: Tone.
   // Date    : 15-12-2003.
  
   // Ref: Dates go in "2003-12-31".
   // Ref: Times go in "12:59:13".
   // Ref: mktime(HOUR,MIN,SEC,MONTH,DAY,YEAR).
  
   // Splits the dates into parts, to be reformatted for mktime.
  
$first_date_ex = explode("-",$first_date);
  
$first_time_ex = explode(":",$first_time);
  
$second_date_ex = explode("-",$second_date);
  
$second_time_ex = explode(":",$second_time);
  
  
// makes the dates and times into unix timestamps.
  
$first_unix  = mktime($first_time_ex[0], $first_time_ex[1], $first_time_ex[2], $first_date_ex[1], $first_date_ex[2], $first_date_ex[0]);
  
$second_unix  = mktime($second_time_ex[0], $second_time_ex[1], $second_time_ex[2], $second_date_ex[1], $second_date_ex[2], $second_date_ex[0]);

  
// Gets the difference between the two unix timestamps.
  
$timediff = $first_unix-$second_unix;
              
  
// Works out the days, hours, mins and secs.
  
$days=intval($timediff/86400);
  
$remain=$timediff%86400;
  
$hours=intval($remain/3600);
  
$remain=$remain%3600;
  
$mins=intval($remain/60);
  
$secs=$remain%60;

  
// Returns a pre-formatted string. Can be chagned to an array.
  
return $days . " days " . $hours . " hours<br> " . $mins . " mins";
}
?>
tperrett at butlerandtanner dot com
06-Jan-2006 11:38
Handy function for working out the number of days until and event, its basic, but does what i need it too and may help somone else as this wasnt easily obvious to me when trying to do it. cheers

function fromnow($from){
   if($from) {
     $r = ((mktime(0,0,0,date('m'),date('d'),date('Y')) - $from) / 86400);
       return number_format($r,0);
   } else {
       return null;
   }
}
chris@NnOoSwPhAeMre dot gov
25-Dec-2005 10:27
<?
/*************** 

Take a date from a credit card stored in a mysql database and see when it expires based on today's date.

$row[account_exp] = 1/2006

eg.
echo "$cc_exp_month/$cc_exp_year ($cc_exp_string)"
shows you  1/2006 (7 DAYS)

****************/
list($cc_exp_month,$cc_exp_year) = explode("/", $row[account_exp]);
       if ( (
$cc_exp_month && $cc_exp_year ) && ( mktime() > mktime(0,0,0,$cc_exp_month,1,$cc_exp_year ) ) ) {
              
$is_expired = TRUE;
              
$cc_exp_string = "<font color=red>".EXPIRED."</font>";
       } elseif (
$cc_exp_month && $cc_exp_year ) {
              
$is_expired = FALSE;
              
$time  = mktime(0,0,0,$cc_exp_month,1,$cc_exp_year) - mktime();
              
$time  = round($time / (24 * 60 * 60));
              
$time .= " ".DAYS;
              
$cc_exp_string = "<font color=green>".$time."</font>";
       }
php at cNhOiSpPpAlMe dot org
06-Dec-2005 01:34
This is an update to my f_IsDstUS() function posted on 22-Apr-2004 05:37.
(http://php.net/manual/en/function.mktime.php#41785)
It now takes account for the Energy Policy Act of 2005 (effective in 2007).

Is it DST in the US on/at $dDate? (Regional exceptions not included.)
Ref.: http://webexhibits.org/daylightsaving/b.html

I use this function to calculate time differences between a server located in the US and a region not affected by DST, and vice-versa.

<?

function f_IsDstUS ($dDate) {
 
/* Energy Policy Act of 2005 (effective in 2007) */
 
$bEnergyPolicyAct2005 = (intval(date("Y",$dDate)) >= 2007);

  if (
$bEnergyPolicyAct2005) {
  
/* FROM 2007 */
   /* DST START (Second Sunday in March at 2am) */
  
$dMarch1stDay = mktime(
                      
0,0,0,
                      
3,1,date("Y",$dDate));
  
$dMarch2ndSunday = $dMarch1stDay
                    
+((7-date("w",$dMarch1stDay))%7+7)*(60*60*24);
  
$dDstStart = mktime(
                  
2,0,0,
                  
date("m",$dMarch2ndSunday),
                  
date("d",$dMarch2ndSunday),
                  
date("Y",$dMarch2ndSunday));

  
/* DST END (First Sunday in November at 2am) */
  
$dNovember1stDay = mktime(
                        
0,0,0,
                        
11,1,date("Y",$dDate));
  
$dNovember1stSunday = $dNovember1stDay
                        
+((7-date("w",$dNovember1stDay))%7)*(60*60*24);
  
$dDstEnd = mktime(
                  
2,0,0,
                  
date("m",$dNovember1stSunday),
                  
date("d",$dNovember1stSunday),
                  
date("Y",$dNovember1stSunday));
  }
  else {
  
/* BEFORE 2007 */
   /* DST START (First Sunday in April at 2am) */
  
$dApril1stDay = mktime(
                      
0,0,0,
                      
4,1,date("Y",$dDate));
  
$dApril1stSunday = $dApril1stDay
                    
+((7-date("w",$dApril1stDay))%7)*(60*60*24);
  
$dDstStart = mktime(
                  
2,0,0,
                  
date("m",$dApril1stSunday),
                  
date("d",$dApril1stSunday),
                  
date("Y",$dApril1stSunday));

  
/* DST END (Last Sunday in October at 2am) */
  
$dOctoberLastDay = mktime(
                        
0,0,0,
                        
11,0,date("Y",$dDate));
  
$dOctoberLastSunday = $dOctoberLastDay
                        
-(date("w",$dOctoberLastDay))*(60*60*24);
  
$dDstEnd = mktime(
                
2,0,0,
                
date("m",$dOctoberLastSunday),
                
date("d",$dOctoberLastSunday),
                
date("Y",$dOctoberLastSunday));
  }

 
/* DST INDEX */
 
return intval$dDate >= $dDstStart
              
&& $dDate < $dDstEnd);
}

// Sample usage:
$iHoursToLocal = 15-f_IsDstUS(time());
$dLocal = mktime(
            
date("H")+$iHoursToLocal,date("i"),date("s"),
            
date("m"),date("d"),date("Y"));

?>
ian at opensystems dot net dot au
14-Nov-2005 04:21
A trivial way to avoid having to remember the quirky order of variables.

It's also more convenient to use because you can ignore the last three (time) variables if all you want to do is manupulate the date components.

Just include the following function at the top of your script and call ansi_mktime instead of mktime.

function ansi_mktime($y=0, $month=0, $d=0, $h=0, $min=0, $s=0){
   return mktime($h, $min, $s, $month, $d, $y);
}

// eg:
$day = 14;
echo date("dS \d\a\y of M Y", ansi_mktime(2005, 11, $day + 7))

// output: 21st day of Nov 2005
mickyfunk at hotmail dot com
08-Nov-2005 05:26
<?
/*    This program work out the difference between 2 dates one been the current date and the
   is set by changing the numbers in $pastdate. This could easily be configured to accept
   input from a form.*/

   //this sets the variable $today to todays date
  
$today = date("d/m/Y");

  
//this sets the variable $birthday to the date selected
  
$pastdate = date("18/11/1983");

  
//this seperates the $today into an array
  
$explodetoday = explode("/", $today);

  
//this makes a timestamp out of the exploded date this number is in seconds
  
$stoday = mktime(0, 0, 0, $explodetoday[1], $explodetoday[0], $explodetoday[2]);

  
$explodepastdate = explode("/", $pastdate);
  
$spastdate = mktime(0, 0, 0, $explodepastdate[1], $explodepastdate[0], $explodepastdate[2]);

  
//this works out the difference between today and the date set.
  
$sDifference = $stoday - $spastdate;

  
//this works out the age of the person in years
  
$yDifference = ($sDifference / 60 / 60 / 24 / 365.25);

  
$yDifferences = number_format($yDifference, 2);
  
   echo(
"$yDifferences Years Old\n");

?>

Not as good as some others but this is the first real bit of code i have created.
pr10n at spymac dot com
28-Oct-2005 01:05
This is the method I use to determine a user's age in years. Perhaps not as fancy as some others but it hasn't failed me yet.

<?php
  
function get_age($dob_stamp) {
      
$dob = getdate($dob_stamp);
      
$now = getdate(time());
      
$age = $now['year'] - $dob['year'];
      
$age-= (int)($now['mon'] < $dob['mon']);
      
$age-= (int)(($now['mon'] == $dob['mon']) && ($now['mday'] < $dob['mday']));
       return
$age;
   }
?>
eidolon at idealsound dot ca
26-Oct-2005 03:30
There was a birthdate calculator posted above which from reading the code seems flawed in my logic.

Oddly, most code I see to calculate birthdates tries to use the difference between the years to find it's result, which can be flawed (if my birthday is Jan 10th and I'm 19, and its Jan 5th, these scripts might still think I am 20). Basically this creates a timestamp with the desired birthdate and only checks if the given birthdate has passed this year yet or not. Simple & reliable age in years!

Here's the code I use to do this, which, yes, could be better written:

$bd = mktime(0,0,0,$month,$day,$year);

if (date("n") > intval($month)) {$before = FALSE;}
if (intval(date("j")) >= intval($day)) {$before = FALSE;}
else {$before=TRUE;}

if ($before == TRUE) { $age = (date("Y")-$year)-1; }
else { $age = (date("Y")-$year); }
alborz at myweblog dot com
22-Sep-2005 08:16
This is how you would convert a MySQL datetime to RFC 822 for RSS

$breakup = $row->date;

                                           list($date, $hours) = split(' ', $breakup);
                                           list($year,$month,$day) = split('-',$date);
                                           list($hour,$min,$sec) = split(':',$hours);
                                           $date = date(r,mktime($hour, $min, $sec, $month, $day, $year));
larry at mlxpert dot com
09-Sep-2005 12:40
I needed a script to display a dropdown menu with a list of week ending dates. I wrote this as a result. I hope it helps somebody. The selname variable is the name of the select field and the day of week of the begining date designates the end of the week.

<?php
$selname
="we_date";
//Build Begin date
$month=10;
$day=04;
$year=2003;
$hour=date('H');
$min=date('i');
$sec=date('s');

//convert it to unix timestamp
$bdate=mktime($hour,$min,$sec,$month,$day,$year);

//Build Today   
$thour=date('H');
$tmin=date('i');
$tsec=date('s');
$tmonth=date('n');
$tday=date('d');
$tyear=date('Y');
//convert it to unix timestamp
$today=mktime($thour,$tmin,$tsec,$tmonth,$tday,$tyear);

    
//just the weeks
$nbdate=floor($bdate/(7 * 24 * 60 * 60));
$ntoday=floor($today/(7 * 24 * 60 * 60));

//difference between today and the beginning date
$diff=$today-$bdate;
echo
"<select size='1' name='$selname'>\n";
while (
$bdate <= $today+(7 * 24 * 60 * 60)){
echo (
"<option value='".date('n/d/Y',$bdate)."'>
"
.date('n/d/Y',$bdate)."</option>\n");

$bdate=$bdate+(7 * 24 * 60 * 60);
}
echo
"</select>";
?>
funkisyourfriend at gmail dot com
07-Aug-2005 06:25
In response to Hayden...

I hate to inform you of this after you've worked out your own function for date validation, but PHP has a function called checkdate(). It does the exact same thing as your isvaliddate() function.
agentleon at navigator dot lv
02-Aug-2005 02:23
This is probably due to DST or anything like this, but this code:

print(date('d.m.Y',mktime(0,0,0,9,30,1990)+3600*24));

will print out "30.09.1990", instead of "01.10.1990". This works when year is <=1990, when it is >=1991, everything works fine. PHP ver. 4.3.7
luke at mudbugmedia dot com
23-Jul-2005 12:31
In response to phpprince at phpprince dot com:

The same thing can be done with

<?php
echo date('Y-m-d H:i:s', strtotime('+7 days'));
?>
ceo at diveintojens dot org
30-Jun-2005 03:49
Quote by Matt... Just a note: If month has a zero before it (IE '03'), mktime will not like it and give you an output of -1

Solution: Use (int)$month instead of $month

Best regards,
Jens Rybacke
phpprince at phpprince dot com
10-Jun-2005 10:11
i was writing a mini auction script and tried to replicate ebay's 7 day listing. so if you post your auction today, it will end exactly 7 days later, exact up to the seconds.

$today = date("Y-m-d H:i:s"); // get today's date

$sep = explode(" ",$today); // split into day and time
$day = $sep[0];
$time = $sep[1];

$timesep = explode(":",$time); // split time into hr, min, sec
$hour = $timesep[0];
$min = $timesep[1];
$sec = $timesep[2];

$enddate = mktime($hour,$min,$sec, date("m"),date("d")+7,date("Y")); // add 7 to the day, the hour, minutes and second are grabbed from the current time using variables from the $timesep explode

$enddate = date("Y-m-d H:i:s", $enddate); // the enddate

echo $enddate;

voila!
venimus777 at yahoo dot com
09-Jun-2005 12:20
You may consider easier to calculate dates using strtotime() instead of mktime():

<?
   date
('Y-m-d',strtotime('now +'.$f.' months'));
?>

will produce the date $f($f>=0) months after today.
Hayden
07-Jun-2005 08:33
Here is a quick way to check the a date is valid. I use this when I get users to enter dates via drop downs, which leave open the possibility for impossible dates like 30-Feb-2005 and 31-Jun-2005 etc. This is only necessary as mktime() will accept these invalid dates, which is, in my case, sometimes not the desired handling.

<?php
function isvaliddate($day, $month, $year) {
  
$day = intval($day);
  
$month = intval($month);
  
$year = intval($year);
  
$time = mktime(0,0,0,$month,$day,$year);
   if (
$day != date("j",$time)) return false;
   if (
$month != date("n",$time)) return false;
   if (
$year != date("Y",$time)) return false;
   return
true;
}
?>

Note that date("Y",$time) checks the year as a 4 digit year. That line could be replaced as shown below to allow for the 2 digit notation as well.
Also the order the arguments need to be specified is day, month, year, because I come from NZ and that is the format we use here. If you prefer another format, for example month, day, year, just change the order of the arguments on the first line.

<?php
function isvaliddate($day, $month, $year) {
  
$day = intval($day);
  
$month = intval($month);
  
$year = intval($year);
  
$time = mktime(0,0,0,$month,$day,$year);
   if (
$day != date("j",$time)) return false;
   if (
$month != date("n",$time)) return false;
   if ((
$year != date("Y",$time)) AND ($year != date("y",$time))) return false;
   return
true;
}
?>

Hope this helps someone!
Cheers,
Hayden.
caliban at darklock dot com
27-May-2005 09:40
cdblog at gmail dot com didn't clarify exactly what his function does: it returns the week number WITHIN THE CURRENT MONTH, i.e. the first day of the month is in week 1, the eighth day is in week 2, the fifteenth is in week 3, the 22nd is in week 4, and the 29th is in week 5. A useful function, if you need such things.
cdblog at gmail dot com
27-May-2005 05:06
<?php
  
/**
   * @return int
   * @desc get the week's No. by day.
   * @link http://php.clickz.cn/articles/date/getWeekNoByDay,html
   * @update at my php blog, http://php.clickz.cn/
   */
  
function getWeekNoByDay($year = 2005,$month = 5,$day = 5) {
       return
ceil(($day + date("w",mktime(0,0,0,$month,1,$year)))/7);   
   }
?>
taum at free dot fr
21-May-2005 11:49
in response to chrisrobins at NOSPAM dot gmail dot com's note :

You may as well use MySQL's UNIX_TIMESTAMP() function to convert a mysql timestamp to a unix timestamp.
Here is a simple example :

<?php

// Query the database
$q = mysql_query("SELECT date, UNIX_TIMESTAMP(date) AS timestamp FROM table");
$row = mysql_fetch_array($q);

// then use PHP's date() function :
$date = date("F j, Y, g:i a", $row['timestamp']);

echo
"$row[date] = $date"; // Will output : 2005-05-21 18:09:43 = May 21, 2005, 6:09 pm

?>

Should be faster that using some regular expressions or other user-defined functions, and IMHO a lot easier ;-)
jemore at m6net dot fr
07-May-2005 01:39
A date enumerator function. With this, you set a begin date and an end date (timestamp format), and it will call a user function stepping one day or one month.

<?php
define
('DATE_ENUM_DAY', 1);
define ('DATE_ENUM_MONTH', 2);
/*
 * enumerate a date and call a user function
 * dateBeginTS, dateEndTS : Timestamp date
 * callbackfunc : name of the php function to callback
 *  this cb function receive 2 parameters : the current enumerated date (timestamp) and the $param parameter
 * step : DATE_ENUM_DAY or DATE_ENUM_MONTH
 * param : a user parameter
 */
function date_enumeration($dateBeginTS, $dateEndTS, $callbackfunc, $step, $param = NULL)
{
  
$cur = $dateBeginTS;
   while(
$cur <= $dateEndTS)
   {
      
$callbackfunc($cur, &$param);
      
       if (
$step == DATE_ENUM_DAY)
       {
          
$cur = mktime(
              
date('h', $cur),
              
date('i', $cur),
              
date('s', $cur),
              
date('m', $cur),
              
date('d', $cur) + 1,
              
date('Y', $cur));
       }
       else if (
$step == DATE_ENUM_MONTH)
       {
          
$cur = mktime(
              
date('h', $cur),
              
date('i', $cur),
              
date('s', $cur),
              
date('m', $cur) + 1,
              
date('d', $cur),
              
date('Y', $cur));
       }
       else
       {
           die (
'No step specified');
       }
   }
}

/// SAMPLE USAGE
function cb_test($timestamp, $param)
{
   echo
date('r', $timestamp), ' ', $param, "<br>\n";
}

date_enumeration(
  
mktime(0,0,0,1,1,2000),
  
mktime(0,0,0,1,1,2002),
  
'cb_test',
  
DATE_ENUM_DAY
);

?>
Greg Robbins
06-May-2005 12:42
Here's an update (no pun intended) to my "generic times" function below for comverting between timestamps and hours, minutes and seconds, but that don't represent any particular date.

The previous functions return values that are incorrectly offset by 1 hour (3600 seconds) when you are in daylight savings time.

Here are revised functions that take into account whether or not you are on daylight savings time.

These 2 functions let you convert back and forth between human-readable H:M:S format and non-negative, GMT-agnostic (and DST-agnostic!!) timestamps for when you are working only with hours, minutes, and seconds.

<?php
function hms_2_ts($hms) //expects 24 hour time expressed like
                       //00:00:01 for "one second after midnight"
{
  
$offset = date(Z);    //your local offset in seconds from GMT
  
  
$is_dls = date(I) == 1 ? true : false; //date(I) returns 1 if in DST, 0 if not
  
  
if($is_dls) $offset -= 3600; //Roll back one hour if you are in DST
  
  
$hms_arr = explode(":", $hms);
  
  
$h = $hms_arr[0];
  
$m = $hms_arr[1];
  
$s = $hms_arr[2] + $offset;    //Compensate for GMT offset
  
  
$ts = mktime($h, $m, $s, 1, 1, 1970, 0);
  
   return
$ts;
}

function
ts_2_hms($ts)
{
  
$offset = date(Z);
  
  
$is_dls = date(I) == 1 ? true : false; //date(I) returns 1 if in DST, 0 if not
  
  
if($is_dls) $offset -= 3600; //Roll back one hour if you are in DST
  
  
$ts += 86400;    //no "before 1970" errors on Windows this way.
                   //This will make the date wrong, but we're only
                   //dealing with H:M:S so it shouldn't matter
  
  
$ts -= $offset;    //Compensate for GMT offset
  
  
return date("H:i:s", $ts);
}

//Check it out:
echo "offset = " . date(Z) . "<br>";

$hms = "00:00:01";
echo
"hms = $hms<br>";

$ts = hms_2_ts($hms);
echo
"ts = $ts<br>";

$hms_again = ts_2_hms($ts);
echo
"hms again = $hms_again";
?>

I suggest that "Daylight Savings Time" could also be called "Programmers' Wasting Time" :)
webmaste at caleidosmultimedia dot com
27-Apr-2005 08:42
My little code for make a code to get the difference between dates

<?
$data1
= mktime (0,0,0,5,5,2005); //specify a date1
$data2 = mktime (0,0,0,5,15,2005); //specify a date2

$differenza = ($data2 - $data1 ) / 86400;

echo
" The Different $data2 - data1 = $differenza";
?>
armando at scribano dot com dot ar
21-Apr-2005 05:12
This function return date (format d/m/Y) of N monday

$fechalunes1 = buscalunes($lunes='1');

function buscalunes($lunes)
{
   //busca N lunes y da el dia
   $fecha    = date ("Ymd");
   $ano = substr ($fecha,0, 4);
   $mes = substr ($fecha,4, -2);
   $dia = substr ($fecha,6,8);
   $con=1;
   while($contlunes!=$lunes)
   {
       $dia_chr = date( "l", mktime(0,0,0,$mes,$dia-$con,$ano));       
       if($dia_chr=='Monday')
       {
           $fechalunes = date( "d/m/Y", mktime(0,0,0,$mes,$dia-$con,$ano));
           $contlunes++;
       }
       $con ++;
      
   }
   return $fechalunes ;
}
forums at jefferyfernandez dot id dot au
15-Apr-2005 11:33
With response to Robert Christiaanse's Delphi related convertion to find the
day in the week of a year, here is my solution

The original purpose of this function was to return the "first day of the week"
for a timesheet application. Since PHP defaults to Monday as the start of the
week, and the need for my app to have Sunday as the start of the week, I had to
pass the day as an argument. So if you call the function like:

find_first_day_ofweek(16, 2005, 'sunday');

it would return the unix timestamp of the Sunday in week 16 of 2005.
 
<?php   
/**
 * Function to find the day of a week in a year
 * @param integer $week The week number of the year
 * @param integer $year The year of the week we need to calculate on
 * @param string  $start_of_week The start day of the week you want returned
 *                Monday is the default Start Day of the Week in PHP. For
 *                example you might want to get the date for the Sunday of wk 22
 * @return integer The unix timestamp of the date is returned
 */
function find_first_day_ofweek($week, $year, $start_of_week='sunday')
{
  
// Get the target week of the year with reference to the starting day of
   // the year
  
$target_week = strtotime("$week week", strtotime("1 January $year"));

  
// Get the date information for the day in question which
   // is "n" number of weeks from the start of the year
  
$date_info = getdate($target_week);

  
// Get the day of the week (integer value)
  
$day_of_week = $date_info['wday'];

  
// Make an adjustment for the start day of the week because in PHP the
   // start day of the week is Monday
  
switch (strtolower($start_of_week))
   {
       case
'sunday':
          
$adjusted_date = $day_of_week;
           break;
       case
'monday':
          
$adjusted_date = $day_of_week-1;
           break;
       case
'tuesday':
          
$adjusted_date = $day_of_week-2;
           break;
       case
'wednesday':
          
$adjusted_date = $day_of_week-3;
           break;
       case
'thursday':
          
$adjusted_date = $day_of_week-4;
           break;
       case
'friday':
          
$adjusted_date = $day_of_week-5;
           break;
       case
'saturday':
          
$adjusted_date = $day_of_week-6;
           break;

       default:
          
$adjusted_date = $day_of_week-1;
           break;
   }

  
// Get the first day of the weekday requested
  
$first_day = strtotime("-$adjusted_date day",$target_week);

  
//return date('l dS of F Y h:i:s A', $first_day);

  
return $first_day;
}
?>
colin dot horne at gmail dot com
31-Mar-2005 02:48
If the month is greater than 12, it goes into the next year. If it is less than 1, it goes into the previous year. Generally, it behaves as you'd expect it to :-)

Examples:

<?php

// January 1, 2005
print date ("F j, Y", mktime (0,0,0,13,1,2004));

// December 1, 2003
print date ("F j, Y", mktime (0,0,0,0,1,2004));

// February 1, 2005
print date ("F j, Y", mktime (0,0,0,14,1,2004));

// November 1, 2003
print date ("F j, Y", mktime (0,0,0,-1,1,2004));

?>
mariano at cricava dot com
27-Mar-2005 02:22
Here is another way to calculate the difference between two dates. It is based on previous date_diff example, but with the possibility now to specify full dates (dates plus time), and to get the result in different units.

Example of use:

<?php
$dateFrom
= "25-03-2005 14:20:00";
$dateTo = date("d-m-Y H:i:s", strtotime('now'));

$diffd = getDateDifference($dateFrom, $dateTo, 'd');
$diffh = getDateDifference($dateFrom, $dateTo, 'h');
$diffm = getDateDifference($dateFrom, $dateTo, 'm');
$diffs = getDateDifference($dateFrom, $dateTo, 's');
$diffa = getDateDifference($dateFrom, $dateTo, 'a');

echo
'Calculating difference between ' . $dateFrom . ' and ' . $dateTo . ' <br /><br />';

echo
$diffd . ' days.<br />';
echo
$diffh . ' hours.<br />';
echo
$diffm . ' minutes.<br />';
echo
$diffs . ' seconds.<br />';

echo
'<br />In other words, the difference is ' . $diffa['days'] . ' days, ' . $diffa['hours'] . ' hours, ' . $diffa['minutes'] . ' minutes and ' . $diffa['seconds'] . ' seconds.<br>';

?>

Here's the code:

<?php
/**
 * Calculates the difference for two given dates, and returns the result
 * in specified unit.
 *
 * @param string    Initial date (format: [dd-mm-YYYY hh:mm:ss], hh is in 24hrs format)
 * @param string    Last date (format: [dd-mm-YYYY hh:mm:ss], hh is in 24hrs format)
 * @param char    'd' to obtain results as days, 'h' for hours, 'm' for minutes, 's' for seconds, and 'a' to get an indexed array of days, hours, minutes, and seconds
 *
 * @return mixed    The result in the unit specified (float for all cases, except when unit='a', in which case an indexed array), or null if it could not be obtained
 */
function getDateDifference($dateFrom, $dateTo, $unit = 'd')
{
  
$difference = null;

  
$dateFromElements = split(' ', $dateFrom);
  
$dateToElements = split(' ', $dateTo);

  
$dateFromDateElements = split('-', $dateFromElements[0]);
  
$dateFromTimeElements = split(':', $dateFromElements[1]);
  
$dateToDateElements = split('-', $dateToElements[0]);
  
$dateToTimeElements = split(':', $dateToElements[1]);

  
// Get unix timestamp for both dates

  
$date1 = mktime($dateFromTimeElements[0], $dateFromTimeElements[1], $dateFromTimeElements[2], $dateFromDateElements[1], $dateFromDateElements[0], $dateFromDateElements[2]);
  
$date2 = mktime($dateToTimeElements[0], $dateToTimeElements[1], $dateToTimeElements[2], $dateToDateElements[1], $dateToDateElements[0], $dateToDateElements[2]);

   if(
$date1 > $date2 )
   {
       return
null;
   }

  
$diff = $date2 - $date1;

  
$days = 0;
  
$hours = 0;
  
$minutes = 0;
  
$seconds = 0;

   if (
$diff % 86400 <= 0// there are 86,400 seconds in a day
  
{
      
$days = $diff / 86400;
   }

   if(
$diff % 86400 > 0)
   {
      
$rest = ($diff % 86400);
      
$days = ($diff - $rest) / 86400;

       if(
$rest % 3600 > 0 )
       {
          
$rest1 = ($rest % 3600);
          
$hours = ($rest - $rest1) / 3600;

           if(
$rest1 % 60 > 0 )
           {
              
$rest2 = ($rest1 % 60);
              
$minutes = ($rest1 - $rest2) / 60;
              
$seconds = $rest2;
           }
           else
           {
              
$minutes = $rest1 / 60;
           }
       }
       else
       {
          
$hours = $rest / 3600;
       }
   }

   switch(
$unit)
   {
       case
'd':
       case
'D':

          
$partialDays = 0;

          
$partialDays += ($seconds / 86400);
          
$partialDays += ($minutes / 1440);
          
$partialDays += ($hours / 24);

          
$difference = $days + $partialDays;

           break;

       case
'h':
       case
'H':

          
$partialHours = 0;

          
$partialHours += ($seconds / 3600);
          
$partialHours += ($minutes / 60);

          
$difference = $hours + ($days * 24) + $partialHours;

           break;

       case
'm':
       case
'M':

          
$partialMinutes = 0;

          
$partialMinutes += ($seconds / 60);

          
$difference = $minutes + ($days * 1440) + ($hours * 60) + $partialMinutes;

           break;

       case
's':
       case
'S':

          
$difference = $seconds + ($days * 86400) + ($hours * 3600) + ($minutes * 60);

           break;

       case
'a':
       case
'A':

          
$difference = array (
              
"days" => $days,
              
"hours" => $hours,
              
"minutes" => $minutes,
              
"seconds" => $seconds
          
);

           break;
   }

   return
$difference;
}
?>
Romain Sam
25-Mar-2005 11:50
Under Windows, mktime goes until 2038-01-19 (03:14:07 ...)
Matt
24-Mar-2005 02:52
Just a note:
If month has a zero before it (IE '03'), mktime will not like it and give you an output of -1
Greg Robbins
15-Mar-2005 12:12
For a project I need to use "generic times" - just hours, minutes and seconds that don't represent any particular date.

I needed to convert human-readable H:M:S values to timestamp-like integers representing seconds (Example: 00:30:00 becomes 1800). The resulting values are very small; as a result, functions like mktime(), date() & friends think they're dealing with timestamps right around the Unix Epoch.

The problem is the Windows / GMT factor. For some values I got warnings about dates before January 1, 1970 not being accepted by Windows. Then other times I would get unexpected values because of my GMT offset (it happens in the best of families).

Here's 2 functions that should let you convert back and forth between human-readable H:M:S format and non-negative, GMT-agnostic timestamps for when you are working only with hours, minutes, and seconds.

<?php
function hms_2_ts($hms) //expects 24 hour time expressed like
                       //00:00:01 for "one second after midnight"
{
  
$offset = date(Z);    //your local offset in seconds from GMT
  
  
$hms_arr = explode(":", $hms);
  
  
$h = $hms_arr[0];
  
$m = $hms_arr[1];
  
$s = $hms_arr[2] + $offset;    //Compensate for GMT offset
  
  
$ts = mktime($h, $m, $s, 1, 1, 1970, 0);
  
   return
$ts;
}

function
ts_2_hms($ts)
{
  
$offset = date(Z);
  
  
$ts += 86400;    //no "before 1970" errors on Windows this way.
                   //This will make the date wrong, but we're only
                   //dealing with H:M:S so it shouldn't matter
  
  
$ts -= $offset;    //Compensate for GMT offset
  
  
return date("H:i:s", $ts);
}

//Check it out:
echo "offset = " . date(Z) . "<br>";

$hms = "00:00:01";
echo
"hms = $hms<br>";

$ts = hms_2_ts($hms);
echo
"ts = $ts<br>";

$hms_again = ts_2_hms($ts);
echo
"hms again = $hms_again";
?>
maxnamara at yahoo dot com
08-Mar-2005 11:08
How to get the date of next day(s) ?
Please take a look my working code:

<?

function add_zero($a){
  
$b = $a;
   if(
strlen($a) == 1){
      
$b = "0".$a;   
   }   
   return
$b;
}

function
day_th($gmt, $no=30){
  
// default $no = 30 later
          
// get GMT datetime as standard for 'now()'

// $gmt = gmstrftime("%Y-%m-%d %H:%M:%S");

$d = explode(" ",$gmt);
$date = $d[0];
$time = $d[1];

$date_x = explode("-",$date);
$year = $date_x[0];
$month = $date_x[1];
$day = $date_x[2];

$time_x = explode(":",$time);
$hour = $time_x[0];
$minute = $time_x[1];
$second = $time_x[2];

// create UNIX TIMESTAMP of the GMT above
$t = mktime($hour, $minute, $second, $month, $day, $year);

// 1 h = 3600 sec
// 1 d = 24 h
// 1 d = 86400 sec
// 30 d = 2592000 sec

$unix_stamp = 86400 * $no;

$res = getdate($t + $unix_stamp);

$ris = array_values($res);

list(
$seconds,$minutes,$hours,$mday,$wday,$mon,$year,
$yday,$weekday,$month,$unix) = $ris;

$mon = add_zero($mon);
$mday = add_zero($mday);
$seconds = add_zero($seconds);
$minutes = add_zero($minutes);
$hours = add_zero($hours);

$day_th = $year."-".$mon."-".$mday." ".$hours.":".$minutes.":".$seconds;

return
$day_th;
}

// $gmt = gmstrftime("%Y-%m-%d %H:%M:%S");
$gmt = "2005-02-28 00:00:01";

$nextdate = day_th($gmt, $no=1);

echo
$gmt."<br>".$nextdate."<br>";
?>
maxnamara at yahoo dot com
08-Mar-2005 10:35
This is my way to get unix timestamp.

<?
$serverdate
= gmstrftime("%Y-%m-%d %H:%M:%S");
echo
$serverdate."<br>";

function
extract_date($date){
$arr = explode(" ",$date);

$d = $arr[0];
$t = $arr[1];

$arr_d = explode("-",$d);
$year = $arr_d[0];
$year = intval($year);
$month = $arr_d[1];
$month = intval($month);
$day = $arr_d[2];
$day = intval($day);

$arr_t = explode(":",$t);
$hour = $arr_t[0];
$hour = intval($hour);
$minute = $arr_t[1];
$minute = intval($minute);
$second = $arr_t[2];
$second = intval($second);

return array(
$hour, $minute, $second, $month, $day, $year);
}

function
unix_timestamp($date) {
$a = extract_date($date);
$b = mktime($a[0],$a[1],$a[2],$a[3],$a[4],$a[5]);

return
$b;
}

/*
$a = extract_date($serverdate);
echo "<pre>";
print_r($a);
echo "</pre>";
*/

echo "<br><br><br>";
echo
"Unix TimeStamp:<br>";
$b = unix_timestamp($serverdate);
echo
$b."<br>";

?>
the_boy_who_got_lost at yahoo dot com
08-Mar-2005 06:10
Just an example of how to get the date out of a couple of list boxes, for newbe's

<form action="<?=$PHP_SELF ?>" method="post">
<span class="row2"><select name="month" id="month">
               <option selected="selected">Month</option>
               <option>April</option>
               <option>May</option>
               <option>June</option>
               <option>July</option>
               <option>August</option>
               <option>September</option>
               <option>October</option>
             </select>
             <select name="day" id="day">
               <option selected="selected">Day</option>
               <option>1</option>
               <option>2</option>
               <option>3</option>
               <option>4</option>
               <option>5</option>
               <option>6</option>
               <option>7</option>
               <option>8</option>
               <option>9</option>
               <option>10</option>
               <option>11</option>
               <option>12</option>
               <option>13</option>
               <option>14</option>
               <option>15</option>
               <option>16</option>
               <option>17</option>
               <option>18</option>
               <option>19</option>
               <option>20</option>
               <option>21</option>
               <option>22</option>
               <option>23</option>
               <option>24</option>
               <option>25</option>
               <option>26</option>
               <option>27</option>
               <option>28</option>
               <option>29</option>
               <option>30</option>
               <option>31</option>
             </select>
             <select name="year" id="year">
               <option selected="selected">Year</option>
               <option>05</option>
               <option>06</option>
             </select>
             <input name="submit" type="submit" id="submit" value="submit">
</span>
</form>

<?php
if (!isset($_POST['submit'])){

}
//
// form submitted
//
else { 
$Dmonth = $_POST[month];
$Dday = $_POST[day];
$Dyear = $_POST[year];

if (
$Dmonth == 'April') {$r = "4";}
elseif (
$Dmonth == 'May') {$r = "5";}
elseif (
$Dmonth == 'June') {$r = "6";}
elseif (
$Dmonth == 'July') {$r = "7";}
elseif (
$Dmonth == 'August') {$r = "8";}
elseif (
$Dmonth == 'September') {$r = "9";}
elseif (
$Dmonth == 'October') {$r = "10";}
echo
"<br />";
echo
"<br />";
$date1 = date("M-d-y", mktime(0, 0, 0, $r, $Dday, $Dyear));
echo
$date1 ;
echo
"<br />";
echo
date("M-d-y", mktime(0, 0, 0, $r, ++$Dday, $Dyear));
echo
"<br />";
echo
date("M-d-y", mktime(0, 0, 0, $r, ++$Dday, $Dyear));
echo
"<br />";
echo
date("M-d-y", mktime(0, 0, 0, $r, ++$Dday, $Dyear));
}
?>
andreas dot schmeiler at rtlnewmedia dot de
11-Feb-2005 08:41
if you ever wondered how to convert a windows (ASP) Timestamp to an unix Timestamp, try this:

(windowsTime to unixTime):

function wT2uT($win_timestamp) {
 
   $WIN_DATE_CONST=2209165200;
   $WIN_TIME_CONST=115740.74074074;
 
   list($win_date, $win_time)=explode(",",$win_timestamp);
 
   $win_time=substr($win_time."0000000000",0,10);
 
   $ux_date = $win_date*24*60*60;
   $ux_date-= (date("I")*60*60);
   $ux_date-= $WIN_DATE_CONST;
  
   $ux_time = round($win_time/$WIN_TIME_CONST);
  
   return($ux_date+$ux_time);
}
kwillmert a visionaryweb dt com
10-Feb-2005 06:47
A simpler version of the function below:
<?php

function dttm2unixtime( $dttm2timestamp_in )
{
  
//    returns unix time stamp for a given date time string that comes from DB
  
list( $date, $time ) = split(" ", $dttm2timestamp_in);
   list(
$year, $month, $day ) = split( "-", $date );
   list(
$hour, $minute, $second ) = split( ":", $time );

   return
mktime( $hour, $minute, $second, $month, $day, $year );
}

?>

You don't need to run intval on each string, mktime knows what they are and will do that behind the scenes.
dasprid [AT] web [DOT] de
04-Feb-2005 08:42
I have to correct, what Evorg (28-Sep-2004 04:24) wrote. If you want to delete a cookie, simply take the value 0 (zero) as timestamp. It's the same as the timestamp, which Evorg's example generates.
fontajos at phpeppershop dot com
01-Dec-2004 06:19
<?php
// Calculates UNIX timestamps from datestamps counting
// days from 01/01/0000. Used in some DataFlex databases.
// Tested only with Timestamps > 01/01/1970 and
// < 31/12/2025.
// Arguments: $days (Integer, days-from-0000,
//                  e.g. 731168 = 30/10/2001)
function date_diff_value($days) {
  
// 1/1/1970 = 719543 days counting from 01/01/0000
  
$day_1_1_1970 = 719543;
  
$diff = $days - $day_1_1_1970;
  
$unix_ts = $diff * 86400;
   return
$unix_ts;
}
?>
cp at u-help dot org
28-Nov-2004 09:53
I once had to deal with dates coming in as a sting from a mysql database (surprise, surprise ;-)) without having any option to select anything differen (i.e. using mysql's UNIX_TIMESTAMP)
This caused me a lot of problems and I couldn't seem to find anything anywhere that would just take the entire lot as an input to convert it to unix-timestamp.
Maybe someone else finds the below function useful to convert these date/time strings into unix-timestamps

<?php

function dttm2unixtime($dttm2timestamp_in){
  
//    returns unixtime stamp for a given date time string that comes from DB
  
$date_time = explode(" ", $dttm2timestamp_in);
  
$date = explode("-",$date_time[0]);   
  
$time = explode(":",$date_time[1]);   
   unset(
$date_time);
   list(
$year, $month, $day)=$date;
   list(
$hour,$minute,$second)=$time;
   return
mktime(intval($hour), intval($minute), intval($second), intval($month), intval($day), intval($year));
}

?>

A mysql date-time value like "2004-11-28 01:34:20" would be converted to this: 1101605660

As a verification, date("Y-m-d H:i:s", 1101605660) would return the same as the value passed in, i.e. 2004-11-28 01:34:20

Using the function above, you don't have to include any fancy parsing into the retrieval of the results...

hope it helps ;)
phpmanual at localpin dot com
02-Nov-2004 05:03
Daylight saving time!  Grrrrrrrrrr!  (And a minor "Grrr!" for PHP making this less intuitive than it should be).

In brief, NEVER add number of seconds, like 60*60*24, but use strtotime("+1 day", $myDate)).

Some of the 'simple' functions above for calculating dates will NOT work correctly when a date includes daylight saving time.  Shown below is the problem illustrated and a simple solution.

EXAMPLE 1: WRONG!
I had the following loop, which worked fine all year, until this weekend, when the clocks changed, and it broke!  The problem is daylight saving time:

// Loop through dates adding 1 days worth of seconds each time
$myDate = 1098914400  // October 28th
for ($myDate = $fromDate; $myDate <= $toDate;  $myDate = $myDate + 60 * 60 * 24) {
  $printable = strftime("%d-%m-%Y %H:%M:%S", $myDate);
  echo $printable
}

"28-10-2004 00:00:00"
"29-10-2004 00:00:00"
"30-10-2004 00:00:00"
"31-10-2004 00:00:00"
"31-10-2004 23:00:00"  (oops!  31st October repeats and time now 23:00!!)
"01-11-2004 23:00:00"
"02-11-2004 23:00:00"

EXAMPLE 2: CORRECT!
$myDate = 1098914400  // October 28th
for ($myDate = $fromDate; $myDate <= $toDate; $myDate = strtotime("+1 day", $myDate)) {
  $printable = strftime("%d-%m-%Y %H:%M:%S", $myDate);
  echo $printable
}

"28-10-2004 00:00:00"
"29-10-2004 00:00:00"
"30-10-2004 00:00:00"
"31-10-2004 00:00:00"
"01-11-2004 00:00:00"
"02-11-2004 00:00:00"
Evorg
28-Sep-2004 10:24
mktime should be used when removing cookies. Normally people tend to use: time()-3600 to set the expiration date in "the past". The problem with this is that some computers is set at a wrong date and therfore differs from the server-time. That will render the time()-3600 unusable.

Instead use mktime(12,0,0,1, 1, 1990) as you expiration criteria. I'm convinced that only a very few users has set their time back more than 1990 :)
alex at gameserverhost dot nl
15-Sep-2004 05:27
A simple statement to calculate days between two dates

$dayselepsed = round((strtotime($dateone) - strtotime($datetwo))/(60*60*24)-1);

Regards Alex Curvers
jlim at natsoft dot com dot my
25-Jun-2004 08:36
Hi,

For those looking for a solution to the 1970-2038 limitation, the adodb time library does the trick nicely. The website has changed, to

http://phplens.com/phpeverywhere/adodb_date_library

"This library replaces native functions as follows:

   getdate()  with  adodb_getdate()
   date()    with  adodb_date()
   gmdate()  with  adodb_gmdate()
   mktime()  with  adodb_mktime()
   gmmktime() with  adodb_gmmktime()"

Download the inc file:
http://phplens.com/lens/dl/adodb-time.zip

Enjoy, John Lim
noodle at digital-nw dot com
17-May-2004 10:47
If the time has passed and you have not specified a date, mktime will automatically move to the next date. For example:

$hour = '12';
$mins = '37';

$time = mktime($hour,$mins,0,date('n'),date('d'));
echo date("l dS of F Y h:i:s A",$time);

will return something like:

Monday 17th of May 2004 12:37:00 PM

When in actuality it's Sunday 16th of May.
Robert Christiaanse
15-May-2004 01:56
In addition to my post (get date by week number, day of the week and year)...

No Daylight saving was taken into account!!! That's were the 3600 --- It's summertime here now :-)  --- is used for in PHPUnixTimeStamp(), but it's dirty and also wrong.
Robert Christiaanse
15-May-2004 01:47
If you want to get the date of a given day in a week, this might be useful. (I.e. you want to know what is the date of Friday in week 20 of 2004) 
This code was converted from Delphi source code and has been tested. No guarantees however ;-)

<?php

# Get a date by providing a week number, day of week and a year.

# Be careful! There are different definitions for weeks. Here the European definition is used.
# In Europe a week starts on Monday.
# Also the start of the first week in a year is defined differently in different countries.
# Here the ISO 8601 definition is used. This is the standard in Europe.
#
# I got the information from http://home.t-online.de/home/PeterJHaas/delphi.htm
# There are many websites with information on week numbers.
# An excellent site on this subject is http://www.pjh2.de/datetime/weeknumber/index.php
#
# This PHP source was based on the Delphi source code by Peter J. Haas
#
 
 //give me the date of Friday week 20 of the year 2004 (Should result in Friday May 14 2004)
 
$aWeek=20; $aDay=05; $aYear=2004;
 
$adate=datefromweeknr($aYear, $aWeek, $aDay);
 echo
'The date (week='.$aWeek.' day='.$aDay.' year= '.$aYear.') is '.date('D d-m-Y',$adate).'<br>';
 
 function
datefromweeknr($aYear, $aWeek, $aDay)
 {
 
$FirstDayOfWeek=1; //First day of week is Monday       
 
$BaseDate=4; //We calculate from 4/1 which is always in week 1 
 
$CJDDelta=2415019; //Based on start of Chronological Julian Day
 
$StartDate = DelphiDate(mktime(1,0,0,01,$BaseDate,$aYear)); //The date to start with
 
$Offset = ($aWeek-1) * 7 - mod(floor($StartDate) + $CJDDelta + 8 - $FirstDayOfWeek,7) + $aDay - 1;
  return
PHPUnixTimeStamp($StartDate + $Offset);
 }

 
#---------extra functions used----------

 
function DelphiDate($aPHPTime)
 {
  
# The Unix Timestamp holds the number of seconds after January 1 1970 01:00:00
  
return div($aPHPTime,86400)+25569;
 }
 
 function
PHPUnixTimeStamp($aDelphiDate)
 {
  
# Delphi's TDate holds number of days after December 30 1899
  
return ($aDelphiDate-25569)*86400-3600;
 }
 
 function
mod($number, $div)
 {
   return
$number - floor($number/$div)*$div;
 }

 function
div($number, $div)
 {
   return
floor($number/$div);
 }

 
?>
Dave J.
13-May-2004 11:42
bichinhoverde's my_gmmktime function uses an incomplete definition of leap year.  It's not leap year if the year is divisible by 100 and NOT divisible by 400. E.G. 2000 was a leap year, but 2100 will not be. Trivial, but it should be said.

Thus,
   if ( $i % 4 == 0 ) {
     $output += 24*60*60;
   }

should be:
   if ( (($i % 4 == 0) && ($i % 100 != 0))
       || ($i % 400 == 0) ) {
     $output += 24*60*60;
   }
matt at killermookie dot org
23-Apr-2004 08:27
I noticed that while it is legal to do this:

$date=date("Y-m-d", mktime(0,0,0,4,20,2004);

It doesn't quite work the same when you do this:

$time=date("H:i:s", mktime(10,30,15,0,0,0);

No matter what variables you put in for time, it'll always spit out 15:59:59. You need to include the month, day and year if you want it to convert the time.

I spent nearly an hour trying to figure out what I was doing wrong til I stuck in a random date.
php at cNhOiSpPpAlMe dot org
22-Apr-2004 04:37
Is it DST in the US on/at $dDate? (Regional exceptions not included.)
Ref.: http://webexhibits.org/daylightsaving/e.html

I use this function to calculate time differences between a server located in the US and a region not affected by DST, and vice-versa.

<?

function f_IsDstUS ($dDate) {
 
// DST START (First Sunday in April at 2am)
 
$dApril1stDay = mktime(
                    
0,0,0,
                    
4,1,date("Y",$dDate));
 
$dApril1stSunday = $dApril1stDay
                  
+((7-date("w",$dApril1stDay))%7)*(60*60*24);
 
$dDstStart = mktime(
                
2,0,0,
                
date("m",$dApril1stSunday),
                
date("d",$dApril1stSunday),
                
date("Y",$dApril1stSunday));

 
// DST END (Last Sunday in October at 2am)
 
$dOctoberLastDay = mktime(
                      
0,0,0,
                      
11,0,date("Y",$dDate));
 
$dOctoberLastSunday = $dOctoberLastDay
                      
-(date("w",$dOctoberLastDay))*(60*60*24);
 
$dDstEnd = mktime(
              
2,0,0,
              
date("m",$dOctoberLastSunday),
              
date("d",$dOctoberLastSunday),
              
date("Y",$dOctoberLastSunday));

 
// DST?
 
return intval$dDate >= $dDstStart
              
&& $dDate < $dDstEnd);
}

?>
y4yh00 at yahoo dot com
08-Apr-2004 07:58
For those looking for a solution to the 1970-2038 limitation, the adodb time library does the trick nicely.

http://php.weblogs.com/adodb_date_time_library
"This library replaces native functions as follows:

   getdate()  with  adodb_getdate()
   date()    with  adodb_date()
   gmdate()  with  adodb_gmdate()
   mktime()  with  adodb_mktime()
   gmmktime() with  adodb_gmmktime()"

Download the inc file:
http://phplens.com/lens/dl/adodb-time.zip

Enjoy,
rob
joakim stai
29-Mar-2004 02:48
As Nigel pointed out, you should be aware of DST (Daylight Savings Time) when using mktime(). Some systems will return a negative value if you use 0 as the hour, as it will simply skip from (for example) 23:59:59 to 01:00:00. Instead use 12 (noon) as the hour and you won't get a negative timestamp or a date in the 1960's.

This code will work with DST:
$today = mktime(12, 0, 0, date("m"), date("d"), date("Y"));
ed_isthmus at NOSPAMyahoo dot com
08-Mar-2004 10:23
Further to a point iain made earlier, about problems with daylight savings time:
<?php
$timestamp
= mktime(0, 0, 0, 3, 28, 2004);
echo
date('d M Y H:i:s', $timestamp);
?>
Will output '27 Mar 2004 23:00:00' (in the UK)!
Best solution for me was to specify the dst argument:
<?php
$timestamp
= mktime(0, 0, 0, 3, 28, 2004, 0);
?>
Alternatively, you could use gmmktime(); and/or check the timezone offset.
pb at _remove_ pedal dot dk
28-Feb-2004 11:30
I find it easiest, if I want to find you how many days there are between two dates to use the following method:

$init_day = 1;
$init_mth = 1;
$init_yr = 2004;

$dst_day = 5;
$dst_mth = 8;
$dst_yr = 2004;

//first convert to unix timestamp
$init_date = mktime(12,0,0,$init_mth,$init_day,$init_yr);
$dst_date = mktime(12,0,0,$init_mth,$init_day,$init_yr);

$offset = $dst_date-$init_date; //Depending on which offset type you want, switch order

$days = floor($offset/60/60/24);
Nigel Gilbert
16-Feb-2004 04:15
Several posts here offer procedures to compute the number of days between two dates based on using mktime, using the given date and 00:00:00 as the time.  It turns out that this is bad choice for the default time for such calculations when the date in question happens to be the date when daylight savings time starts.  For example, on several OSs, there is no such time as 00:00:00 30-03-2003 (and mktime returns a negative value), because the clock changed from 23:59:59 29-03-2003 straight to 01:00:00 30-03-2003 as a result of Daylight Saving. At better choice is to use, for example, 12,0,0,30,3,2003 as the argument to mktime, that is, use noon, not midnight as the default time.
web at nihongo dot d2g dot com
08-Feb-2004 05:13
<?php

//-----------------------------------------------------------
function date_diff($date_from,$date_to,$unit='d')
/*
Calculates difference from date_from to date_to, taking into account leap years
if date_from > date_to, the number of days is returned negative
date_from and date_to format is: "dd-mm-yyyy"
It can calculate ANY date difference, for example between 21-04-345 and 11-11-3412
This is possible by mapping any date to the "range 0" dates, as this table shows:

   INI            END            RANGE    LEAP YEARS
   ...            ...            ...        ...
   01/01/1920    01/01/1939    -3        5
   01/01/1940    01/01/1959    -2        5
   01/01/1960    01/01/1979    -1        5
   01/01/1980    01/01/1999    0        5    * this is the range used for calculations with mktime
   01/01/2000    01/01/2019    1        5
   01/01/2020    01/01/2039    2        5
   01/01/2040    01/01/2059    3        5
   01/01/2060    01/01/2079    4        5
   ...            ...            ...        ...

The difference is calculated in the unit specified by $unit (default is "days")
$unit:
   'd' or 'D' = days
   'y' or 'Y' = years
*/

{
  
//get parts of the dates
  
$date_from_parts = explode('-', $date_from);
  
$date_to_parts = explode('-', $date_to);
  
$day_from = $date_from_parts[0];
  
$mon_from = $date_from_parts[1];
  
$year_from = $date_from_parts[2];
  
$day_to = $date_to_parts[0];
  
$mon_to = $date_to_parts[1];
  
$year_to = $date_to_parts[2];

  
//if date_from is newer than date to, invert dates
  
$sign=1;
   if (
$year_from>$year_to) $sign=-1;
   else if (
$year_from==$year_to)
       {
       if (
$mon_from>$mon_to) $sign=-1;
       else if (
$mon_from==$mon_to)
           if (
$day_from>$day_to) $sign=-1;
       }

   if (
$sign==-1) {//invert dates
      
$day_from = $date_to_parts[0];
      
$mon_from = $date_to_parts[1];
      
$year_from = $date_to_parts[2];
      
$day_to = $date_from_parts[0];
      
$mon_to = $date_from_parts[1];
      
$year_to = $date_from_parts[2];
       }

   switch (
$unit)
       {
       case
'd': case 'D': //calculates difference in days           
      
$yearfrom1=$year_from//actual years
      
$yearto1=$year_to;      //(yearfrom2 and yearto2 are used to calculate inside the range "0")   
       //checks ini date
      
if ($yearfrom1<1980)
           {
//year is under range 0
          
$deltafrom=-floor((1999-$yearfrom1)/20)*20; //delta t1
          
$yearfrom2=$yearfrom1-$deltafrom;          //year used for calculations
          
}
       else if(
$yearfrom1>1999)
           {
//year is over range 0
          
$deltafrom=floor(($yearfrom1-1980)/20)*20; //delta t1
          
$yearfrom2=$yearfrom1-$deltafrom;          //year used for calculations           
          
}
       else {
//year is in range 0
          
$deltafrom=0;
          
$yearfrom2=$yearfrom1;
           }
          
      
//checks end date
      
if ($yearto1<1980) {//year is under range 0
          
$deltato=-floor((1999-$yearto1)/20)*20; //delta t2
          
$yearto2=$yearto1-$deltato;            //year used for calculations
          
}
       else if(
$yearto1>1999) {//year is over range 0
          
$deltato=floor(($yearto1-1980)/20)*20; //delta t2
          
$yearto2=$yearto1-$deltato;            //year used for calculations           
          
}
       else {
//year is in range 0
          
$deltato=0;
          
$yearto2=$yearto1;
           }
  
      
//Calculates the UNIX Timestamp for both dates (inside range 0)
      
$ts_from = mktime(0, 0, 0, $mon_from, $day_from, $yearfrom2);
      
$ts_to = mktime(0, 0, 0, $mon_to, $day_to, $yearto2);
      
$diff = ($ts_to-$ts_from)/86400;
      
//adjust ranges
      
$diff += 7305 * (($deltato-$deltafrom) / 20);
       return
$sign*$diff;
       break;
      
       case
'y': case 'Y': //calculates difference in years
      
$diff=$year_to-$year_from;       
      
$adjust=0;
       if (
$mon_from>$mon_to) $adjust=-1;
       else if (
$mon_from==$mon_to)
           if (
$day_from>$day_to) $adjust=-1;
      
       return
$sign*($diff+$adjust);
       break;       
       }
}

?>
praas at NOSPAM dot ision dot nl
01-Feb-2004 04:44
Consider skipping months with mktime().

$nextmonth = date("M",mktime(0,0,0,date("n")+1,date("j"),date("Y")));

On any day in Januari you expect to get Feb, right?
But on January 30th you'll get Mar. It will try Feb 30th, which doesn't exist, and skips another month. Therefore in this case present a day value that will certainly be legal in any month, like day "1".

This will give you next month on any day of the year:
$nextmonth = date("M",mktime(0,0,0,date("n")+1,1,date("Y")));
marcbs78 at gmx dot net
20-Jan-2004 10:43
The function MakeTime() of todd at buiten dot com does work very well but there is al little problem with the introduction of summer/winter time.

In Germany this time is introduced in 1980. So if we shift the timezone from 1952-1969 to 1980-1997 you'll work with summer/winter time but this isn't correct.

This doesn't matter until you'll work only with dates. If you do, you're loosing one hour which means in dates this is one day which is lost.
iain at seatofthepants dot net
09-Dec-2003 11:49
In the above example it should ne boted that if you try to calculate the command at midnight on the 28/04/2004 you will get an erroneous response. This has been driving me to distraction.

$myTime = mktime( 0, 0, 0, 3, 28, 2004);

Solution I found was to create the time at 3am well after the 2am daylight savings problem, viz:

$myTime = mktime( 3, 0, 0, 3, 28, 2004);

Not sure if this is documented anywhere.
todd at buiten dot com
07-Dec-2003 05:14
If you want to calculate dates before 1970 and your OS doesn't support it (Windows and Linux), you can easily write your own wrapper to mktime to do the calculation.  The idea is to find a date range in the 1970-2037 time frame that is the same as your year prior to 1970 (both years start on the same day of the week and leap years are the same), then add that number of years to your year value before calling mktime() and then subtract the corresponding number of seconds from the mktime() result (including the appropriate number of leap seconds).  This way old guys like me (born in 1963) can get a valid number back from mktime() and we can figure out how old we are in seconds.  :-)  You can go all the way back to 1902 if you want.

The mapping is as follows:
1902-1951 = 1986-2035
1952-1969 = 1980-1997
By matching starting day of week for the year and leap years then we should calculate daylight time correctly (assuming that we have the right rules set).  There's a special hack in the code to turn off daylight time prior to 1942 for date().

Here's the code that we're using now:

//
// Replacement for mktime that does dates before 1970
//
function MakeTime()
{
   $objArgs = func_get_args();
   $nCount = count($objArgs);
   if ($nCount < 7)
   {
       $objDate = getdate();
       if ($nCount < 1)
           $objArgs[] = $objDate["hours"];
       if ($nCount < 2)
           $objArgs[] = $objDate["minutes"];
       if ($nCount < 3)
           $objArgs[] = $objDate["seconds"];
       if ($nCount < 4)
           $objArgs[] = $objDate["mon"];
       if ($nCount < 5)
           $objArgs[] = $objDate["mday"];
       if ($nCount < 6)
           $objArgs[] = $objDate["year"];
       if ($nCount < 7)
           $objArgs[] = -1;
   }
   $nYear = $objArgs[5];
   $nOffset = 0;
   if ($nYear < 1970)
   {
       if ($nYear < 1902)
           return 0;
       else if ($nYear < 1952)
       {
           $nOffset = -2650838400;
           $objArgs[5] += 84;
           // Apparently dates before 1942 were never DST
           if ($nYear < 1942)
               $objArgs[6] = 0;
       }
       else
       {
           $nOffset = -883612800;
           $objArgs[5] += 28;
       }
   }
  
   return call_user_func_array("mktime", $objArgs) + $nOffset;
}

In Linux, the values returned will work just fine with date() and I believe that strftime() should work too, but Windows doesn't like the negative values at all.  We had to write a replacement for strtotime since it appears to call mktime() to come up with the final result.

I hope that this helps someone.

- todd
verszuz at hotmail dot com
29-Nov-2003 01:53
I figured out this way to calculate your age using mktime:

<?php

$day
=27;//the day of birth variable
$month=10;//the month of birth variable   
$year=1977;// the year of birth variable

$now=mktime();
echo
$now."<br>";
$timebirth=mktime(0,0,0,$month,$day,$year);
echo
$timebirth."<br>";
$agetime=$now-$timebirth;

echo ((
strftime("%Y",$agetime))-(strftime("%Y",0)));
?>

I hope this will help. Remember this calculator does not work properly on windows because of the limited range of mktime().
sun4php at coolguide dot net
24-Nov-2003 09:36
Very often we are faced with the problem of adjusting ourself to local time where application is running rather than running our application at server time.

Now we have a way to do that by setting TZ variable using putenv() method. But due to the non-availability of standard time zone codes, developers are often faced with the ambiguity of how to implement a non standard time zone(those which are not too popular)

I figured a way out myself for this. It uses the information that a particular time zone is n hours ahead or n hours behind standard GMT time zone.

here is what i did.
<?php

$day
=15;
    
$month=12;
    
$year=2003;
    
//convert it to unix timestamp
    
    
$deadline=mktime('','','',$month,$day,$year);

//caluculate our time from GMT time
    
$hour=gmdate('H');
    
$min=gmdate('i');
    
$sec=gmdate('s');
    
$month=gmdate('n');
    
$day=gmdate('d');
    
$year=gmdate('Y');
    
$stamp=mktime ($hour,$min,$sec,$month,$day,$year);

// technique is to convert the GMT date & time to unix stamp, then convert time zone
     //specific information like add 5 hours or subtract 5 hours to seconds,(consider day
     //light saving here), and add/subtract it to the unix time stamp and then convert
     //it back to date using date function if needed or perform operations needed on the
     // time stamp
    
     //subtract 6/n hours from GMT time (Central standard time/CST)
     //vary this part to whatever time zone you are at
    
$do=6*60*60;
    
$lstamp=$stamp-$do;
     echo(
"Today(local date/Central):".date('h:i:s d/n/Y',$lstamp)."<br>");
    
    
$left=$deadline-$lstamp;
    
    
$days_left=floor($left/(24 * 60 * 60));
    
$hours_left=floor($left/(60 * 60 ));
     echo
"<br>Days Left: $days_left<br>";
     echo
"<br>Hours Left(approx): $hours_left<br>";
    
?>

Change the $do variable to whatever seconds you are different from GMT and add or subtract accordingly to generate $lstamp.

This would solve your time zone problems.

Happy Coding,
Suneel Kanuri
trahma
21-Nov-2003 04:06
I think it is important to note that the timestamp returned is based upon the number of seconds from the epoch GMT, and then modified by the time zone settings on the server.

Thus...

mktime(0,0,0,1,1,1970) will not always return 0.  For example with the US eastern time zone (GMT-5) will return 18000 (5 hours past the epoch) and the same function with the time zone set to the US pacific time zone (GMT-8) will return 28800 (8 hours past the epoch).

In an instance where you want time zone independence, you should use the function gmmktime()
laurie at oneuponedown dot com
19-Nov-2003 12:42
With regard to Example 1 and using mktime to correct out-of-range input.

It should be noted that mktime will implement day light saving amends. Consider the following:

<?
print(date("d/m/Y H:i:s",mktime(0,0,0,3,(27 + 1),2004)));
?>
OUTPUT "28/03/2004 02:00:00"

<?
print(date("d/m/Y H:i:s",(mktime(0,0,0,3,27,2004) + (((1 * 24) * 60) * 60))));
?>
OUTPUT "28/03/2004 00:00:00"

Dependent on your requirements this may or may be desirable