Date/Time 函数
在线手册:中文  英文

mktime

(PHP 4, PHP 5)

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

说明

int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )

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

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

注释

Note:

As of PHP 5.1, when called with no arguments, mktime() throws an E_STRICT notice: use the time() function instead.

参数

hour

小时数。 The number of the hour relative to the start of the day determined by month, day and year. Negative values reference the hour before midnight of the day in question. Values greater than 23 reference the appropriate hour in the following day(s).

minute

分钟数。 The number of the minute relative to the start of the hour. Negative values reference the minute in the previous hour. Values greater than 59 reference the appropriate minute in the following hour(s).

second

秒数(一分钟之内)。 The number of seconds relative to the start of the minute. Negative values reference the second in the previous minute. Values greater than 59 reference the appropriate second in the following minute(s).

month

月份数。 The number of the month relative to the end of the previous year. Values 1 to 12 reference the normal calendar months of the year in question. Values less than 1 (including negative values) reference the months in the previous year in reverse order, so 0 is December, -1 is November, etc. Values greater than 12 reference the appropriate month in the following year(s).

day

天数。 The number of the day relative to the end of the previous month. Values 1 to 28, 29, 30 or 31 (depending upon the month) reference the normal days in the relevant month. Values less than 1 (including negative values) reference the days in the previous month, so 0 is the last day of the previous month, -1 is the day before that, etc. Values greater than the number of days in the relevant month reference the appropriate day in the following month(s).

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。

Note:

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

返回值

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

错误/异常

在每 次调用日期/时间函数时,如果时区无效则会引发 E_NOTICE 错误,如果使用系统设定值或 TZ 环境变量,则会引发 E_STRICTE_WARNING 消息。参见 date_default_timezone_set()

更新日志

版本 说明
5.3.0 mktime() now throws E_DEPRECATED notice if the is_dst parameter is used.
5.1.0 is_dst 参数被废弃。出错时函数返回 FALSE 而不再是 -1。修正了本函数可以接受年月日参数全为零。
5.1.0 When called with no arguments, mktime() throws E_STRICT notice. Use the time() function instead.
5.1.0

现在发布 E_STRICTE_NOTICE 时区错误。

范例

Example #1 基本例子

<?php
// Set the default timezone to use. Available as of PHP 5.1
date_default_timezone_set('UTC');

// Prints: July 1, 2000 is on a Saturday
echo "July 1, 2000 is on a " date("l"mktime(000712000));

// Prints something like: 2006-04-05T01:02:03+00:00
echo date('c'mktime(123452006));
?>

Example #2 mktime() 例子

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

<?php
echo date("M-d-Y"mktime(00012321997));
echo 
date("M-d-Y"mktime(0001311997));
echo 
date("M-d-Y"mktime(000111998));
echo 
date("M-d-Y"mktime(0001198));
?>

Example #3 下个月的最后一天

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

<?php
$lastday 
mktime(000302000);
echo 
strftime("Last day in Feb 2000 is: %d"$lastday);
$lastday mktime(0004, -312000);
echo 
strftime("Last day in Feb 2000 is: %d"$lastday);
?>

注释

Caution

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

参见


Date/Time 函数
在线手册:中文  英文

用户评论:

skinnepa at hotmail dot com (2013-03-26 13:15:46)

Convert Excel whacky-time to timestamp
function exceltoepoch($whackyexceltime) {
if (is_numeric($whackyexceltime)) {
// intify
$int_portion = (int)$whackyexceltime;
// get the decimals
$dec_portion = $whackyexceltime - $int_portion;
// $int portion is days since Jan 1, 1900.
$epoch = new DateTime('1900-01-01');
// remove 2 seems to be the magic number of days to remove.
$epoch->add(new DateInterval("P".($int_portion - 2)."D"));
// get the seconds that are left
$sec = ceil(86400 * $dec_portion);
// add the second to the epoch
$epoch->add(new DateInterval("PT".$sec."S"));
$ret = $epoch->getTimestamp();
unset($epoch);
//echo date("D, d M Y H:i:s", $ret) ."\n\n";
return $ret;
} else {
// probably not a whacky timestamp, lets try to guess it to
// an epoch and pray
$ts = strtotime($whackyexceltime);
//echo date("D, d M Y H:i:s", $ts)."\n\n";
return $ts;
}
}

pascal dot bonderff at gmail dot com (2013-02-12 22:37:32)

To calculate the number of days between two dates, do not take the integer part of the difference is due to the transition to daylight saving time. We must take rounding:

<?php
function dateDiff($start$end) {
$start_ts strtotime($start);
$end_ts strtotime($end);
$diff $end_ts $start_ts;
return 
round($diff 86400);
}
?>

If you use the floor() instead of round() function, the result will be one day less if the start date is before the summer time date and the end date between the summer time date and the winter time date. This is due to the fact that the summer time date is one hour less.

Saravanan Swaminathan (2013-02-02 09:57:28)

Function for Convert Integer Params to Time

<?php

    
function getTimeByHourMinAndSec($hour=NULL$min=NULL$sec=NULL)
    {
        if(!empty(
$hour) && !empty($min) && !empty($sec))
        {
            if(
is_int($hour) && is_int($min) && is_int($sec))
            {
                
$min    $min floor($sec/60);
                
$hour    $hour floor($min/60);
                
$min    $min%60;
                
$sec    $sec%60;
                return 
$hour.':'.$min.':'.$sec;
            }
            else
                return 
'NULL';
        }
        else if(!empty(
$hour) && !empty($min))
        {
            if(
is_int($hour) && is_int($min))
            {
                
$hour    $hour floor($min/60);
                
$min    $min%60;                                
                return 
$hour.':'.$min.':00';
            }
            else
                return 
'NULL';
        }
        else if(!empty(
$hour))
        {
            if(
is_int($hour))
            {
                return 
$hour.':00:00';
            }
            else
                return 
'NULL';
        }
        else
            return 
'NULL';
    }
?>

Jacob Santos (2012-11-09 16:17:05)

Please note that incrementing a date using mktime in a loop is not proper. You could do it, except that there is a far better method found in the DateTime PHP class. Look at the documentation for DateTime::modify, DateTime::add (when supported) and DateTime::sub (when supported).
Also, adding seconds to a time is, well it isn't as easy as it seems, "Hey I'll just add 3600 seconds or 86400 seconds or x seconds!". The phrase once bitten, twice shy is quite applicable with the usage of adding seconds. If you ever had to 'fix' a time by calculating midnight to add the correct number of seconds, then you are doing it wrong.
Luckily, knowing is not a requirement, because DateTime and friends exists, removing the complexity for you.
So if given a choice of
mktime($seconds, $minutes, $hours+1);
and
$datetime->modify('+1 hour');
or
$datetime->add('P1H');
I'll go with the second choice, but probably not the third, unless I was using DateInterval::createFromDateString, so that other developers knew my intent.

arthur dot nicoll at dundeecity dot gov dot uk (2012-10-17 09:29:54)

I do a lot of work using dates and times.
I use mktime() a lot. One wee word of caution over excessive use of incrementing the day parameter. Something I do quite a lot and works great for reasonable ranges.
I recently found, however, that the function gave erroneous results when too many days were added (i.e. around 6 months worth).
Changed to using mktime for the basic date then adding the required seconds to the integer datetime value.

e.g. instead of 

<?php
for ($i=0$i<$no_of_four_week_periods,$i++)
{
   
$curdatetm mktime(0,0,0,4,(1+($i*28)),$curyr);
}
?>

.. try something like ..

<?php
$basedatetm 
mktime(0,0,0,4,1,$curyr);
for (
$i=0$i<$no_of_four_week_periods,$i++)
{
   
$cudatetm $basedatetm + ($i*28*24*60*60);
}
?>

cheers

Alex K. (2012-10-07 21:21:36)

HTML5 form output date like 2012-10-08 converted to timestamp. 

<?php
/**
 * Convert html 5 output like YYYY-MM-DD to timestamp
 * @param str $v date
 * @return int UNIX timestamp
 * 
 */
function prepareDate($v) {
    
$t=explode("-"$v);
    return (
$v) ? mktime(0,0,0,$t[1],$t[2],$t[0]):false;
}

?>

info at microweb dot lt (2010-11-03 07:42:18)

Function to generate array of dates between two dates (date range array)

<?php
function dates_range($date1$date2)
{
   if (
$date1<$date2)
   {
       
$dates_range[]=$date1;
       
$date1=strtotime($date1);
       
$date2=strtotime($date2);
       while (
$date1!=$date2)
       {
           
$date1=mktime(000date("m"$date1), date("d"$date1)+1date("Y"$date1));
           
$dates_range[]=date('Y-m-d'$date1);
       }
   }
   return 
$dates_range;
}

echo 
'<pre>';
print_r(dates_range('2009-12-25''2010-01-05'));
echo 
'</pre>';
?>

[EDIT BY danbrown AT php DOT net: Contains a bugfix submitted by (carlosbuz2 AT gmail DOT com) on 04-MAR-2011, with the following note: The first date in array is incorrect.]

xr714 at yahoo dot com (2010-10-07 08:58:05)

One of the many problems with Daylight Saving Time / Summer Time is the ambiguity when a specified local time value can refer to two different actual times!  This happens when the local time value is within the relapse range caused by the clocks being set back to proper time.  (eg. if the DST/ST bias is +1 hour, and DST/ST terminates at 02:00 local time, a local time value of 01:30 occurs twice in the same day!)

Because the mktime() function only returns one value, it silently chooses whether to return the time-stamp for the first iteration or the second iteration of a specified local time within this critical range.

To get both possible time-stamps for a local time, compatible with any system locale, time zone, and applicable DST/ST rules, the following function can be used:

<?php /*><!--*/
function LocalToUT($LocalYear$LocalMonth$LocalMonthDay$LocalHour24$LocalMinute$LocalSecond) {
/* Converts local date/time to Universal Time values.  Returns both
possible UT values when local time value is within relapse range
(due to Daylight Saving Time / Summer Time termination).
Notes:
    Conversion based on TZ and DST/ST rules used by mktime() function.
    UT time-stamps are number of UT seconds since midnight Jan 1, 1970 UTC.
    UT does not have leap seconds; a UT second is "stretched" by 2x duration
to maintain synchronization with UTC when a UTC leap second elapses.
Inputs:    All inputs are numeric; $LocalHour24 is in 24-hour format.
Returns: Array:
    'initial' = UT time-stamp of first occurrence of specified local date/time
    'relapse' = UT time-stamp of second occurrence, when local time relapses upon DST/ST termination
*/
    
$UTValue mktime($LocalHour24$LocalMinute$LocalSecond$LocalMonth$LocalMonthDay$LocalYear);
    
$ReturnData = array('initial' => $UTValue'relapse' => $UTValue);
    
//Test for DST/ST transition since prev day
    
$Bias $UTValue mktime($LocalHour24$LocalMinute$LocalSecond$LocalMonth$LocalMonthDay 1$LocalYear) - 86400;    //(-) = DST/ST commence, (+) = DST/ST terminate
    
if ($Bias == 0) {    //No DST/ST transition detected since prev day
        //Test for DST/ST transition up to next day
        
$Bias mktime($LocalHour24$LocalMinute$LocalSecond$LocalMonth$LocalMonthDay 1$LocalYear) - $UTValue 86400;    //(-) = DST/ST commence, (+) = DST/ST terminate
    
}
    if (
$Bias 0) {    //DST/ST termination detected
        
if (date('Z'$UTValue) !== date('Z'$UTValue $Bias)) {    //Local time occurred in relapse range; System assumed 1st iteration
            
$ReturnData['relapse'] = $UTValue $Bias;
        }
        if (
date('Z'$UTValue $Bias) !== date('Z'$UTValue)) {    //Local time occurred in relapse range; System assumed 2nd iteration
            
$ReturnData['initial'] = $UTValue $Bias;
        }
        
//Else local time is outside of relapse range
    
}    //Else no DST/ST transition, or transition is commencement
    
return $ReturnData;
}
/*--></?php */?>

Do not be confused by the start and end tags; The interleaved PHP-comment and HTML-comment delimiters prevent PHP code containing ">" from appearing as literal text when viewing or editing an HTML file with embedded PHP code.

tom at chegg dot com (2010-08-31 14:01:22)

I was using the following to get a list of month names.
for ($i=1; $i<13; $i++) {
echo date('F', mktime(0,0,0,$i) . ",";
}
Normally this outputs -
January,February,March,April,May,June,July,August,
September,October,November,December
However if today's date is the 31st you get instead:
January,March,March,May,May,July,July,August,October,
October,December,December
Why? Because Feb,Apr,June,Sept, and Nov don't have 31 days!
The fix, add the 5th parameter, don't let the day of month default to today's date:
echo date('F', mktime(0,0,0,$i,1) . ",";

zfowler at unomaha dot edu (2010-03-16 14:18:21)

Proper way to convert Excel dates into PHP-friendly timestamps using mktime():

<?php
// The date 6/30/2009 is stored as 39994 in Excel
$days 39994;

// But you must subtract 1 to get the correct timestamp
$ts mktime(0,0,0,1,$days-1,1900);

// So, this would then match Excel's representation:
echo date("m/d/Y",$ts);
?>

Excel uses "number of days since Jan. 1, 1900" to store its dates.  It also treats 1900 as a leap year when it wasn't, thus there is an extra day which must be accounted for in PHP (and the rest of the world).  Subtracting 1 from Excel's number will fix this problem.

contact at phpmember dot com (2010-01-19 16:45:49)

How many days have  passed since the beginning of the year.... regardless of what year it is...

<?php
//Carlos Galindo
//phpmember.com

$days floor((time()-mktime(null,null,null,1,0,date("Y")))/86400);
            
echo 
"$days days have passed";

//Good Luck
?>

cebleo at n-trance dot net (2009-09-08 11:36:57)

to ADD or SUBSTRACT times NOTE that if you dont specify the UTC zone your result is the difference +- your server UTC delay.

if you are ina utc/GMT +1

<?php
$hours_diff 
strtotime("20:00:00")-strtotime("19:00:00");
echo  
date('h:i'$hours_diff)." Hours";
?>

it shows: 02:00 Hours

but if you use a default UTC time:

<?php
date_default_timezone_set
('UTC');
$hours_diff strtotime("20:00:00")-strtotime("19:00:00");
echo 
"<br>"date('h:i'$hours_diff);
?>

it shows: 01:00 Hours.

p2409 at hotmail dot com (2009-08-02 08:49:56)

How to get the first and last dates of the last quarter - useful for things like tax return dates etc.  by Justin

<?php
function getLastQuarter() {
    
// Returns an array with a start and end date for the last quarter from todays date
    // eg. If today is 23 Feb 2009, returns $x['start'] = 1 Oct 2008, $x[end] = 31 Dec 2008
    
$year date("Y",mktime());
    
$month date("m",mktime());
    
// Formula to get a quarter in the year from a month
    
$startmth $month - (($month-1) % );
    
// Fix up Jan - Feb to get LAST year's quarter dates (Oct - Dec)
    
if ($startmth == -2) {
        
$startmth+=12;
        
$year-=1;
    }
    
$endmth $startmth+2;
    
$last_quarter['start'] = mktime(0,0,0,$startmth,1,$year);
    
$last_quarter['end'] = mktime(0,0,0,$endmth,date("t",mktime(0,0,0,$endmth,1,$year)),$year);
    return 
$last_quarter;    
}

// Example - print first and last dates of last quarter.
echo "First day of last quarter was : " date("d-M-Y",$lastquarter['start']) . "\n";
echo 
"Last day of last quarter was : " date("d-M-Y",$lastquarter['end']) . "\n";

// For 2 August 2009, returns:
//    First day of last quarter was : 01-Apr-2009
//    Last day of last quarter was : 30-Jun-2009
//
?>

lucianoiw at hotmail dot com (2009-03-13 05:48:03)

Convert timestamp to time();

<?php
function wp_mktime($_timestamp ''){
    if(
$_timestamp){
        
$_split_datehour explode(' ',$_timestamp);
        
$_split_data explode("-"$_split_datehour[0]);
        
$_split_hour explode(":"$_split_datehour[1]);

        return 
mktime ($_split_hour[0], $_split_hour[1], $_split_hour[2], $_split_data[1], $_split_data[2], $_split_data[0]);
    }
}
?>

[NOTE BY danbrown AT php DOT net: See also (http://php.net/strtotime)]

admin at stipe dot info (2009-02-16 02:12:30)

With combination of mktime and getDate and date() you can add hours / seconds / days / months / years to ANY timestamp. Use strtotime() function to convert any type of dates to timestamp

<?php
    
public function addMonthToDate($timeStamp$totalMonths=1){
        
// You can add as many months as you want. mktime will accumulate to the next year.
        
$thePHPDate getdate($timeStamp); // Covert to Array    
        
$thePHPDate['mon'] = $thePHPDate['mon']+$totalMonths// Add to Month    
        
$timeStamp mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']); // Convert back to timestamp
        
return $timeStamp;
    }
    
    public function 
addDayToDate($timeStamp$totalDays=1){
        
// You can add as many days as you want. mktime will accumulate to the next month / year.
        
$thePHPDate getdate($timeStamp);
        
$thePHPDate['mday'] = $thePHPDate['mday']+$totalDays;
        
$timeStamp mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']);
        return 
$timeStamp;
    }

    public function 
addYearToDate($timeStamp$totalYears=1){
        
$thePHPDate getdate($timeStamp);
        
$thePHPDate['year'] = $thePHPDate['year']+$totalYears;
        
$timeStamp mktime($thePHPDate['hours'], $thePHPDate['minutes'], $thePHPDate['seconds'], $thePHPDate['mon'], $thePHPDate['mday'], $thePHPDate['year']);
        return 
$timeStamp;
    }
?>

ronnie dot kurniawan at gmail dot com (2009-01-16 09:49:27)

Add (and subtract) unixtime:

<?php
function utime_add($unixtime$hr=0$min=0$sec=0$mon=0$day=0$yr=0) {
  
$dt localtime($unixtimetrue);
  
$unixnewtime mktime(
      
$dt['tm_hour']+$hr$dt['tm_min']+$min$dt['tm_sec']+$sec,
      
$dt['tm_mon']+1+$mon$dt['tm_mday']+$day$dt['tm_year']+1900+$yr);
  return 
$unixnewtime;
}
?>

Alan (2008-11-18 07:52:32)

Do remember that, counter-intuitively enough, the arguments for month and day are inversed (or middle-endian). A common mistake for Europeans seems to be to feed the date arguments in the expected order (big endian or little endian).
It's clear to see where this weird order comes from (even with the date being big endian the order for all arguments would still be mixed - it's obviously based on the American date format with the time "prefixed" to allow an easier shorthand) and why this wasn't changed (passing the values in the wrong order produces a valid, though unexpected, result in most cases), but it continues to be a source of confusion for me whenever I come back to PHP from other languages or libraries.

yan (2008-11-10 05:50:06)

caculate days between two date

<?php
  
// end date is 2008 Oct. 11 00:00:00
  
$_endDate mktime(0,0,0,11,10,2008);
  
// begin date is 2007 May 31 13:26:26
  
$_beginDate mktime(13,26,26,05,31,2007);

  
$timestamp_diff$_endDate-$_beginDate +;
  
// how many days between those two date
  
$days_diff $timestamp_diff/86400;

?>

Maffu (2008-10-29 03:05:58)

When calling mktime(), be sure that you use values without leading zeros. The date comes out wrong in the following example:
$endts = mktime(12, 00, 00, 12, 08, 2008, 0);
(note the 08 instead of just 8)
C's scanf() has a format specification where leading 0's can indicate an octal value - perhaps this is related?

ionut dot bodea at eydos dot ro (2008-10-02 08:29:54)

Here is what I use to calculate age. It took me 30 minutes to write and it's quite accurate. What it has special is that it's calculating the number of days a year has (float number), by testing if a year is a leap one or not. This number is used to compute the age.

<?php
function get_age($date_start$date_end) {
    
$t_lived get_timestamp($date_end) - get_timestamp($date_start);
    
$seconds_one_year get_days_per_year($date_start$date_end) * 24 60 60;
    
$age = array();
    
$age['years_exact'] = $t_lived $seconds_one_year;
    
$age['years'] = floor($t_lived $seconds_one_year);
    
$seconds_remaining $t_lived $seconds_one_year;
    
$age['days'] = round($seconds_remaining / (24 60 60));
    return 
$age;
}
function 
get_timestamp($date) {
    list(
$y$m$d) = explode('-'$date);
    return 
mktime(000$m$d$y);
}
function 
get_days_per_year($date_start$date_end) {
    list(
$y1) = explode('-'$date_start);
    list(
$y2) = explode('-'$date_end);
    
$years_days = array();
    for(
$y $y1$y <= $y2$y++) {
        
$years_days[] = date('L'mktime(00011$y)) ? 366 365;
    }
    return 
round(array_sum($years_days) / count($years_days), 2);
}

$date_birth '1979-10-12';
$date_now date('Y-m-d');

$age get_age($date_birth$date_now);
echo 
'<pre>';
print_r($age);
echo 
'</pre>';
?>


It will display something like this:
Array
(
    [years_exact] => 28.972974329491
    [years] => 28
    [days] => 355
)

ooogla at hotmail dot com (2008-09-01 15:56:14)

If you want to increment the day based on a variable when using a loop you can use this when you submit a form
1. Establish a start date and end date in two different variables
2. Get the number of days between a date
$ndays = (strtotime($_POST['edate']) - strtotime($_POST['sdate'])) / (60 * 60 * 24);
Then here is the string you slip in your loop
$nextday = date('Y-m-d', mktime(0, 0, 0, date("m", strtotime($_POST['sdate'])) , date("d", strtotime($_POST['sdate']))+ $count, date("Y", strtotime($_POST['sdate']))));
$count is incremented by the loop.

thomas_corthals at hotmail dot com (2008-05-13 07:34:21)

It seems mktime() doesn't return negative timestamps on Linux systems with a version of glibc <= 2.3.3.

joseph dot andrew dot hughes at gmail dot com (2008-01-30 12:58:39)

Just a small thing to think about if you are only trying to pull the month out using mktime and date. Make sure you place a 1 into day field. Otherwise you will get incorrect dates when a month is followed by a month with less days when the day of the current month is higher then the max day of the month you are trying to find.. (Such as today being Jan 30th and trying to find the month Feb.)

PHPcoder at freemail dot ig3 dot net (2007-09-06 10:58:29)

The maximum possible date accepted by mktime() and gmmktime() is dependent on the current location time zone.
For example, the 32-bit timestamp overflow occurs at 2038-01-19T03:14:08+0000Z. But if you're in a UTC -0500 time zone (such as EST in North America), the maximum accepted time before overflow (for older PHP versions on Windows) is 2038-01-18T22:14:07-0500Z, regardless of whether you're passing it to mktime() or gmmktime().

Jonathan Woodard (2007-08-31 07:31:05)

NB: one 'gotcha' with the implementation of mktime()'s parameters:

<?php
for( $i ;  $i <= 12 $i++ )
{
    echo 
"Month '$i' is: " date"F" mktime$i ) ) . "\n";
}
?>
Will output:
Month '1' is: January
Month '2' is: March
Month '3' is: March
Month '4' is: May
Month '5' is: May
Month '6' is: July
Month '7' is: July
Month '8' is: August
Month '9' is: October
Month '10' is: October
Month '11' is: December
Month '12' is: December
on the 31st day of every month.

Why? Because the 5th parameter "day" defaults to "right now," which will not work reliably for days after the 28th.

To make sure this doesn't happen, specify the first day of the month:
<?php
mktime
$i )
?>

rlz (2007-07-16 21:52:47)

Finding out the number of days in a given month and year, accounting for leap years when February has more than 28 days.

<?php
function days_in_month($year$month) {
    return( 
date"t"mktime000$month1$year) ) );
}
?>

Hope it helps a soul out there.

mike at mike-griffiths dot co dot uk (2007-07-11 06:04:06)

It may be useful to note that no E_WARNINGS or E_NOTICES are give if you specify a date <1901 or >2038 on systems where time_t is a 32bit signed integer.
If a date is specified outside of the allowed range you may get some unexpected results as no timestamp will be returned.

rga at merchantpal dot com (2007-03-31 08:46:06)

You cannot simply subtract or add month VARs using mktime to obtain previous or next months as suggested in previous user comments (at least not with a DD > 28 anyway).

If the date is 03-31-2007, the following yeilds March as a previous month. Not what you wanted.

<?php
$dateMinusOneMonth 
mktime(000, (3-1), 31,  2007 );
$lastmonth date("n | F"$dateMinusOneMonth);
echo 
$lastmonth;    //---> 3 | March
?>

mktime correctly gives you back the 3rd of March if you subtract 1 month from March 31 (there are only 28 days in Feb 07).

If you are just looking to do month and year arithmetic using mktime, you can use general days like 1 or 28 to do stuff like this:

<?php
$d_daysinmonth 
date('t'mktime(0,0,0,$myMonth,1,$myYear));     // how many days in month
$d_year date('Y'mktime(0,0,0,$myMonth,1,$myYear));        // year
$d_isleapyear date('L'mktime(0,0,0,$myMonth,1,$myYear));    // is YYYY a leapyear?

$d_firstdow date('w'mktime(0,0,0,$myMonth,'1',$myYear));     // FIRST falls on what day of week (0-6)
$d_firstname date('l'mktime(0,0,0,$myMonth,'1',$myYear));     // FIRST falls on what day of week Full Name

$d_month date('n'mktime(0,0,0,$myMonth,28,$myYear));         // month of year (1-12)
$d_monthname date('F'mktime(0,0,0,$myMonth,28,$myYear));         // Month Long name (July)
$d_month_previous date('n'mktime(0,0,0,($myMonth-1),28,$myYear));         // PREVIOUS month of year (1-12)
$d_monthname_previous date('F'mktime(0,0,0,($myMonth-1),28,$myYear));     // PREVIOUS Month Long name (July)
$d_month_next date('n'mktime(0,0,0,($myMonth+1),28,$myYear));         // NEXT month of year (1-12)
$d_monthname_next date('F'mktime(0,0,0,($myMonth+1),28,$myYear));         // NEXT Month Long name (July)
$d_year_previous date('Y'mktime(0,0,0,$myMonth,28,($myYear-1)));        // PREVIOUS year
$d_year_next date('Y'mktime(0,0,0,$myMonth,28,($myYear+1)));        // NEXT year

$d_weeksleft = (52 $d_weekofyear);                     // how many weeks left in year
$d_daysinyear $d_isleapyear 366 365;                // set correct days in year for leap years
$d_daysleft = ($d_daysinyear $d_dayofyear);                // how many days left in year
?>

Stephen (2007-01-08 02:43:06)

There are several warnings here about using mktime() to determine a date difference because of daylight savings time. However, nobody seems to have mentioned the other obvious problem, which is leap years.
Leap years mean that any effort to use mktime() and time() to determine the age (positive or negative) of some timestamp in years will be flawed. There are some years that are 366 days long, therefore you cannot say that there is a set number of seconds per year.
Timestamps are good for determining *real* time, which is not the same thing as *human calendar* time. The Gregorian calendar is only an approximation of real time, which is tweaked with daylight savings time and leap years to make it conform more to humans' expectations of how time should or ought to work. Timestamps are not tweaked and therefore are the only authoritative way of recording in computers a proper order of succession of events, but they cannot be integrated with a Gregorian system unless you take both leap years and DST into account. Otherwise, you may get the wrong number of years when you are approaching a value of exactly X years.
As for PHP, you could still use timestamps as a way of determining age if you took into account not only DST but also whether or not each year is a leap year and adjusted your calculations accordingly. However, this could become messy and inefficient.
There is an alternative approach to calculating days given the day, month and year of the dates to be compared. Compare the years first, and then compare the month and day - if the month and day have already passed (or, if you like, if they match the current month and day), then add 1 to the total for the years.
This solution works because it stays within the Gregorian system and doesn't venture into the world of timestamps.
There is also the issue of leap seconds, but this will only arise if you literally need to get the *exact* age in seconds. In that case, of course, you would also need to verify that your timestamps are exactly correct and are not delayed by script processing time, plus you would need to determine whether your system conforms to UTC, etc. I expect this will hardly be an issue for anybody using PHP, however if you are interested there is an article on this issue on Wikipedia:
http://en.wikipedia.org/wiki/Leap_second

jsebfranck (2006-11-07 04:42:14)

There are several notes for mktime which use the number 86400 to differentiate two days. However this technique may pose a problem in case there is a day where the hour change between the two dates to compare.

Consequently, if you want the timestamp difference between the day where the hour change and the next day, it will not be equals to 86400 but either 82800 in case its the winter change of hour day or 90000 for the summer change of hour day.

For example in 2006 :

<?php
echo mktime(0,0,0,10,29,2006) - mktime(0,0,0,10,30,2006); // -90 000
?>

colin dot horne at gmail dot com (2005-03-30 22:48:55)

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));

?>

Romain Sam (2005-03-25 07:50:15)

Under Windows, mktime goes until 2038-01-19 (03:14:07 ...)

praas at NOSPAM dot ision dot nl (2004-02-01 00:44:21)

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")));

trahma (2003-11-20 12:06:38)

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 (2003-11-18 08:42:02)

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:

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

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

Dependent on your requirements this may or may be desirable

易百教程