strtotime

(PHP 3 >= 3.0.12, PHP 4, PHP 5)

strtotime -- 将任何英文文本的日期时间描述解析为 Unix 时间戳

说明

int strtotime ( string time [, int now] )

本函数预期接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳(自 January 1 1970 00:00:00 GMT 起的秒数),其值相对于 now 参数给出的时间,如果没有提供此参数则用系统当前时间。

本函数将使用 TZ 环境变量(如果有的话)来计算时间戳。自 PHP 5.1.0 起有更容易的方法来定义时区用于所有的日期/时间函数。此过程在 date_default_timezone_get() 函数页面中有说明。

注: 如果给定的年份是两位数字的格式,则其值 0-69 表示 2000-2069,70-100 表示 1970-2000。

参数

time

被解析的字符串,格式根据 GNU Date Input Formats 语法

now

用来计算返回值的时间戳

返回值

成功则返回时间戳,否则返回 FALSE。在 PHP 5.1.0 之前本函数在失败时返回 -1

更新日志

版本说明
5.1.0 失败时返回 FALSE,不再是 -1

范例

例子 1. strtotime() 例子

<?php
echo strtotime("now"), "\n";
echo
strtotime("10 September 2000"), "\n";
echo
strtotime("+1 day"), "\n";
echo
strtotime("+1 week"), "\n";
echo
strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo
strtotime("next Thursday"), "\n";
echo
strtotime("last Monday"), "\n";
?>

例子 2. 失败检查

<?php
$str
= 'Not Good';

// previous to PHP 5.1.0 you would compare with -1, instead of false
if (($timestamp = strtotime($str)) === false) {
    echo
"The string ($str) is bogus";
} else {
    echo
"$str == " . date('l dS of F Y h:i:s A', $timestamp);
}
?>

注释

警告

在 PHP 5 中到 5.0.2 之前,"now" 和其它相对时间从今天午夜起错误计算了。这和正确从当前时间起计算的其它版本不同。

注: 有效的时间戳通常从 Fri, 13 Dec 1901 20:45:54 GMT 到 Tue, 19 Jan 2038 03:14:07 GMT(对应于 32 位有符号整数的最小值和最大值)。不是所有的平台都支持负的时间戳,那么日记范围就被限制为不能早于 Unix 纪元。这意味着在 1970 年 1 月 1 日之前的日期将不能用在 Windows,一些 Linux 版本,以及几个其它的操作系统中。不过 PHP 5.1.0 及更新的版本克服了此限制。

参见

strptime()


add a note add a note User Contributed Notes
bad at php dot com
03-Nov-2006 12:41
pzi42 - your solution won't work in months like january when it has to go back to the 28th of febuary.  the simplest solution I can think of to fix the problem of day 31 is to avoid using PHP all together and use a SQL query like this:

SELECT DATE_ADD(`date` , INTERVAL 1 MONTH );
pzi42 at gmx dot de
31-Oct-2006 06:40
simple workaround for the problem of day 31

function incmonth ($increment,$now=-1) {
  $now = ($now == -1)? $now = time() : $now;
 
  if (date('m',$now) <> date('m',$now+86400)) $now -= 86400;

  return strtotime ($increment . ' month',$now);
}
16-Oct-2006 05:50
Be careful, strtotime("+1 month", strtotime("2006-05-31"));
returns 2006-07-01!
sgutauckis
06-Oct-2006 03:02
The following produces the wrong results:
<?php
  
echo date('l, F jS Y', strtotime("third wednesday", strtotime("2006-11-01"))) . "<br>";
   echo
date('l, F jS Y', strtotime("third sunday", strtotime("2006-01-01")));
?>
Produces:
Wednesday, November 22nd 2006
Sunday, January 22nd 2006

The problem stems from strtotime when the requested day falls on the date passed to strtotime. If you look at your calendar you will see that they should return:

Wednesday, November 15th 2006
Sunday, January 15th 2006

Because the date falls on the day requested it skips that day.
25-Aug-2006 06:44
My users want to skip to a certain week and I have looked in vain for a function which would give me dates for a specified week, or even the first day of a certain week. The function below is perhaps overly complicated, partly because my provider runs pre PHP 5.1.0. An ISO week starts with Monday, hence the need for day conversion.

// ******************************************************
// Function that returns the dates for each day in a week
// ******************************************************
function week_dates($week,$year) {
   $week_dates = array();
   // Get timestamp of first week of the year
   $first_day = mktime(12,0,0,1,1,$year);
   $first_week = date("W",$first_day);
   if ($first_week > 1) {
       $first_day = strtotime("+1 week",$first_day); // skip to next if year does not begin with week 1
   }
   // Get timestamp of the week
   $timestamp = strtotime("+$week week",$first_day);

   // Adjust to Monday of that week
   $what_day = date("w",$timestamp); // I wanted to do "N" but only version 4.3.9 is installed :-(
   if ($what_day==0) {
       // actually Sunday, last day of the week. FIX;
       $timestamp = strtotime("-6 days",$timestamp);
   } elseif ($what_day > 1) {
       $what_day--;
       $timestamp = strtotime("-$what_day days",$timestamp);
   }
   $week_dates[1] = date("Y-m-d",$timestamp); // Monday
   $week_dates[2] = date("Y-m-d",strtotime("+1 day",$timestamp)); // Tuesday
   $week_dates[3] = date("Y-m-d",strtotime("+2 day",$timestamp)); // Wednesday
   $week_dates[4] = date("Y-m-d",strtotime("+3 day",$timestamp)); // Thursday
   $week_dates[5] = date("Y-m-d",strtotime("+4 day",$timestamp)); // Friday
   $week_dates[6] = date("Y-m-d",strtotime("+5 day",$timestamp)); // Saturday
   $week_dates[7] = date("Y-m-d",strtotime("+6 day",$timestamp)); // Sunday
   return($week_dates);
}
francisw at alchemetrics dot co dot uk
22-Aug-2006 04:43
re: javascript versus php by news at mycoolstuff dot de

I believe it is because you are in Germany, (CET=+1hr) in the summer (Daylight savings = +1hr) so PHP is giving you the correct time locally, whereas the javascript UTC gives you the GMT (unfortunately renamed to UTC). So the times are the same, but not in the same timezone.

Hope this helps
12-Aug-2006 04:46
If you are having problems with strtotime not recognizing your date try using :
strtotime(str_replace('-','/',$your_date)).

On my system strtotime doesn't seem to understand that 10-01-2006 is a date but happily accepts 10/01/2006

Hope this helps some of you.
nicolas at smileandsoft dot com dot ar
04-Aug-2006 03:22
This probably can be done easier.

First day of this quarter:

<?php
echo strftime( '%Y%m%d', strtotime( strftime( '%Y' ) . '-' . ( ceil( strftime( '%m' )/3 )*3-2 ).'-1' ) );
?>
news at mycoolstuff dot de
16-Jul-2006 01:09
Be careful if you use combined JavaScript and PHP with strtotime you have to keep in mind, that you may get different timestamps. The following code will generate the same timestaps:

<?php
  
echo strtotime("2006-07-31 02:00:00");
?>

<script type="text/javascript">
document.writeln(Date.UTC(2006, 06, 31, 0, 0, 0));
</script>

First you have to notice, that the Javascript Date.UTC function starts months counting with 0, not with 1 (for january) - this is documented well. But what I did not know and took me some time to find out is that you need to modify the time in strtotime() (for me it's 2 hours more than the JavaScript time). This maybe has something to do with GMT on local server, but I have no idea, so if you should know the reason why, please let me know.

Bernhard
dcarter at acromediainc dot com
14-Jul-2006 02:52
Get Quarters:

This is how you find quarters for the current year.

//get our year
$year = date('Y');
//month = janurary
$month =1;
while($month<=12){
   $quarter = strtotime(date("Y-m-d", mktime(0, 0, 0, $month, 1, $year)));
   echo $quarter.'<br>';
   $month = $month +3;
}
develop at STRIP_SPAM dot jjkiers dot nl
11-Jul-2006 08:05
Please be warned that the strtotime function doesn't exactly follow the formats as specified in the GNU manual.

That manual states that 20:02:00.000000 is a valid time. However, when I tell strtotime to use it, it just gives -1, which it shouldn't.

It should instead give something like 1152568884.
d_spagnoli at yahoo dot it
11-May-2006 06:18
The GNU manual page has moved, the new address is

http://www.gnu.org/software/shishi/ manual/html_node/Date-input-formats.html
francesco at pnpitalia dot it
30-Apr-2006 01:09
modifies function of Jae Lee, this one support dates without separator like "20060401", it return a "string" not a "timestamp"
<?php
/**
 * Returns a formatted date from a string based on a given format
 *
 * Supported formats
 *
 * %Y - year as a decimal number including the century
 * %m - month as a decimal number (range 1 to 12)
 * %d - day of the month as a decimal number (range 1 to 31)
 *
 * %H - hour as decimal number using a 24-hour clock (range 0 to 23)
 * %M - minute as decimal number
 * %s - second as decimal number
 * %u - microsec as decimal number
 * @param string date  string to convert to date
 * @param string format expected format of the original date
 * @return string rfc3339 w/o timezone YYYY-MM-DD YYYY-MM-DDThh:mm:ss YYYY-MM-DDThh:mm:ss.s
 */
function parseDate( $date, $format ) {
 
// Builds up date pattern from the given $format, keeping delimiters in place.
 
if( !preg_match_all( "/%([YmdHMsu])([^%])*/", $format, $formatTokens, PREG_SET_ORDER ) ) {
   return
false;
  }
  foreach(
$formatTokens as $formatToken ) {
  
$delimiter = preg_quote( $formatToken[2], "/" );
   if(
$formatToken[1] == 'Y') {
    
$datePattern .= '(.{1,4})'.$delimiter;
   } elseif(
$formatToken[1] == 'u') {
    
$datePattern .= '(.{1,5})'.$delimiter;
   } else {
    
$datePattern .= '(.{1,2})'.$delimiter;
   } 
  }

 
// Splits up the given $date
 
if( !preg_match( "/".$datePattern."/", $date, $dateTokens) ) {
   return
false;
  }
 
$dateSegments = array();
  for(
$i = 0; $i < count($formatTokens); $i++) {
  
$dateSegments[$formatTokens[$i][1]] = $dateTokens[$i+1];
  }
 
 
// Reformats the given $date into rfc3339
 
 
if( $dateSegments["Y"] && $dateSegments["m"] && $dateSegments["d"] ) {
   if( !
checkdate ( $dateSegments["m"], $dateSegments["d"], $dateSegments["Y"] )) { return false; }
  
$dateReformated =
    
str_pad($dateSegments["Y"], 4, '0', STR_PAD_LEFT)
     .
"-".str_pad($dateSegments["m"], 2, '0', STR_PAD_LEFT)
     .
"-".str_pad($dateSegments["d"], 2, '0', STR_PAD_LEFT);
  } else {
   return
false;
  }
  if(
$dateSegments["H"] && $dateSegments["M"] ) {
  
$dateReformated .=
    
"T".str_pad($dateSegments["H"], 2, '0', STR_PAD_LEFT)
     .
':'.str_pad($dateSegments["M"], 2, '0', STR_PAD_LEFT);
    
   if(
$dateSegments["s"] ) {
    
$dateReformated .=
      
":".str_pad($dateSegments["s"], 2, '0', STR_PAD_LEFT);
     if(
$dateSegments["u"] ) {
      
$dateReformated .=
      
'.'.str_pad($dateSegments["u"], 5, '0', STR_PAD_RIGHT);
     }
   }
  }

  return
$dateReformated;
}
?>
Michal Till
19-Apr-2006 10:52
Warning, for example in Czech, we use the month-day-year order, for example 17. 5. 2006 for the 17th of May. This needs to be converted to day-month-year for example, otherwise it will be interpreted as the 5th day in 17th month, returning -1.
jacques dot malan at gmail dot com
11-Apr-2006 07:08
I have had some inconsistancies that was not immediately evident and suggested that strtotime treated my date formats in different ways.
I had trouble with the date format: d/m/Y

I eliminated the inconsistancies by changing the date format to one where (i guess) php does not try and guess the right format. In my case I changed it to the format (d-M-Y) in which case it worked.

Example when trying to find a person's age where:

//$date in format (d/m/Y) was inconsistant but fixed when in format (d-M-Y), e.g. (01-January-2001)

$age = (time() - strtotime($date))/(60*60*24*360);
logistiker
25-Mar-2006 01:27
strtotime is a great function assuming you use 64-bit libraries.  If you don't and you try to use dates outside the 32-bit timestamp, then it's totally useless.  Here's a function that can manipulate years, months and days for an actual date:

function dateAdd($dateValue, $number = 1, $datePart = 'd', $inputDateFormat = 'ymd', &$parsedDate = false){
   //return false if date value is not a date
   if (! isDate($dateValue, $inputDateFormat, $arrDate)) return false;
   //if $number is a decimal, just round to the nearest integer
   if (! is_int($number)) $number = round($number);
   $currentYear = $arrDate['year'];
   $currentMonth = $arrDate['month'];
   $currentDay = $arrDate['day'];
   switch ($datePart){
       case 'y':
           $currentYear = $arrDate['year'] + $number;
       break;
       case 'm':
           $currentYear += ($number < 0) ? ceil($number / 12) : floor($number / 12);
           $currentMonth += $number % 12;
           if ($currentMonth <= 0) $currentMonth += 12;
           if ($currentMonth > 12){
               $currentMonth -= 12;
               $currentYear++;
           }
           //Convert the year to 4 digits so the isDate function will validate the date (only validates 4 digit years)
           $currentYear = toIsoYear($currentYear);
           //If the day doesn't exist in the next month then decrement to the last day of the month
           while (! isDate("$currentYear-$currentMonth-$currentDay")) $currentDay--;
       break;
       case 'd':
           $numLoopDays = abs($number);
           for ($i = 0; $i < $numLoopDays; $i++){
               $currentDay = ($number >= 0) ? $currentDay + 1 : $currentDay - 1;
               if ($currentDay > daysInMonth($currentMonth, $currentYear) || $currentDay < 1){
                   $currentMonth = ($number >= 0) ? $currentMonth + 1 : $currentMonth - 1;
                   if ($currentMonth == 13){
                       $currentMonth = 1;
                       $currentYear++;
                   }
                   if ($currentMonth == 0){
                       $currentMonth = 12;
                       $currentYear--;
                   }
                   $currentDay = ($currentDay < 1) ? daysInMonth($currentMonth, $currentYear) : 1;
               }
           }
       break;
   }
   //iso 8601 requires zero padding for years between -999 and 999
   $currentYear = toIsoYear($currentYear);
   //iso 8601 requires zero padding for months & days < 10
   $currentMonth = toIsoMonthDay($currentMonth);
   $currentDay = toIsoMonthDay($currentDay);
   //parsed date
   $parsedDate['year'] = $currentYear;
   $parsedDate['month'] = $currentMonth;
   $parsedDate['day'] = $currentDay;
   //iso 8601 date output
   $newDate = "$currentYear-$currentMonth-$currentDay";
   return $newDate;
}
Alexander Vasarab
17-Mar-2006 12:48
I'm not sure whether I've overcomplicated this example, but here is my shot at the perfect timezone class. Upon construction, it takes the users timezone (perhaps a setting pulled from a database or session) and the timezone in which the server is located, and the MySQL datetime to be localized. So, for example, if you make a news post to your website at 11:30AM in EST (-5), and a user which is located on the west coast of the US (PST -8) views your website the post time will be displayed in THEIR time (8:30AM). The date() format can be customized as a second parameter of the convert function. Works with any standard timezone. Hopefully, this will save somebody time in the future.

<?php

class timezone {
   var
$user_offset;
  
// users timezone location
  
var $default_offset = -6;
  
// default server timezone location, in this case, US Central Time (-6)
  
var $difference;
   var
$datetime;
  
   function
timezone($user_offset, $default_offset = NULL) {
      
$this->user_offset = $user_offset;
       if(isset(
$default_offset)) $this->default_offset = $default_offset;
      
$this->difference = ($this->user_offset - $this->default_offset);
      
// determine the difference between the users timezone and the servers
  
}
  
   function
convert($datetime, $format = 'M j, Y \a\t g:iA') {
      
$this->difference = (($this->difference >= 0) ? '+' : '') . $this->difference;
      
// add a + in front of the difference if positive
      
if(eregi('.5', $this->difference)) $difference = substr_replace($this->difference, '', -2, 2) . ' hours +30 minutes';
      
// account for a timezone with .5 in it
      
else $difference = $this->difference . ' hours';
      
$this->datetime = strtotime($datetime);
      
$timestamp = strtotime($difference, $this->datetime);
       return
date($format, $timestamp);
   }

}

  
/*
   All possible timezones that will work with this class:
   array(-12, -11, -10, -9, -8, -7,
       -6, -5, -4, -3.5, -3, -2, -1,
       0, 1, 2, 3, 3.5, 4, 4.5, 5, 5.5,
       6, 7, 8, 9, 9.5, 10, 11, 12);
   */
  
  
$users_timezone = 1;
  
// could be stored in a database or $_SESSION
  
$date = '2006-03-16 06:16:33';
  
// a date/time in US Central Time (CT -6)
  
$timezone = new timezone($users_timezone);
  
// create an instance of class timezone
  
print $timezone->convert($date);
  
// returns "Mar 16, 2006 at 1:16PM" to somebody in Paris
  
?>
Ethilien
14-Mar-2006 11:06
If you are using a version of php before date_default_timezone_set() was added, and you want to get a date in GMT, use this function.

<?php
function gmstrtotime ($s)
{
  
$t = strtotime($s);
  
$zone = intval(date("O"))/100;
  
$t += $zone*60*60;
   return
$t;
}
?>
Jae Lee
22-Feb-2006 08:16
To parse UK format of date, just call parseDate( "10/2/2006", "%d/%m/%Y" )

#-----------------------------------------------#
# Purpose  : Returns a timestamp from a string based on the given format and default timezone if it's ambiguous.
#
# Supported formats
#
# %Y - year as a decimal number including the century
# %m - month as a decimal number (range 01 to 12)
# %d - day of the month as a decimal number (range 01 to 31)
#
# %H - hour as a decimal number using a 24-hour clock (range 00 to 23)
# %M - minute as a decimal number
#

function parseDate( $date, $format ) {
   // Builds up date pattern from the given $format, keeping delimiters in place.
   if( !preg_match_all( "/%([YmdHMp])([^%])*/", $format, $formatTokens, PREG_SET_ORDER ) ) {
       return false;
   }
   foreach( $formatTokens as $formatToken ) {
       $delimiter = preg_quote( $formatToken[2], "/" );
       $datePattern .= "(.*)".$delimiter;
   }
  
   // Splits up the given $date
   if( !preg_match( "/".$datePattern."/", $date, $dateTokens) ) {
       return false;
   }
   $dateSegments = array();
   for($i = 0; $i < count($formatTokens); $i++) {
       $dateSegments[$formatTokens[$i][1]] = $dateTokens[$i+1];
   }

   // Reformats the given $date into US English date format, suitable for strtotime()
   if( $dateSegments["Y"] && $dateSegments["m"] && $dateSegments["d"] ) {
       $dateReformated = $dateSegments["Y"]."-".$dateSegments["m"]."-".$dateSegments["d"];
   }
   else {
       return false;
   }
   if( $dateSegments["H"] && $dateSegments["M"] ) {
       $dateReformated .= " ".$dateSegments["H"].":".$dateSegments["M"];
   }
  
   return strtotime( $dateReformated );
}
federico at nextware dot it
20-Feb-2006 08:38
This a simple multi process application where you can choose
the maximun process that can run at the same time.
This is useful when you need to limit the fork of process.
When the MAXPROCESS is reached the program wait on pcntl_wait()
<?

DEFINE
(MAXPROCESS,25);

for (
$i=0;$i<100;$i++){

  
$pid = pcntl_fork();
  
   if (
$pid == -1) {
       die(
"could not fork");
   } elseif (
$pid) {
               echo
"I'm the Parent $i\n";
      
$execute++;
       if (
$execute>=MAXPROCESS){
          
pcntl_wait($status);
          
$execute--;
       }
      

   } else {

       echo
"I am the child, $i pid = $pid \n";
      
sleep(rand(1,3));
       echo
"Bye Bye from $i\n";       
       exit;
   }

}
?>
darb dot 10 at osu dot edu
14-Feb-2006 06:29
PHP 5.1.1

the strtotime function will add 1 day to any leap year date prior to the 1969 cutoff.
Paul Wib
26-Jan-2006 09:37
Slight tweak to ScottB's function for UK dates below. Accounts for when a year isn't provided:

function strtotime_uk($str)
{
   $str = preg_replace("/^\s*([0-9]{1,2})[\/\. -]+([0-9]{1,2})[\/\. -]*([0-9]{0,4})/", "\\2/\\1/\\3", $str);
   $str = trim($str,'/');
   echo "Converted to UK date: $str<br>";
   return strtotime($str);
}

As strtotime, if the year isn't provided it will default to current year:

strtotime_uk("13/11"); // 13th November, UK-style
kturner at kgt dot net
25-Jan-2006 02:18
It looks like in the latest release of PHP 5.1, when passing to strtotime this string "12/32/2005", it will now return the date "12/31/1969". (The previous versions would return "1/1/2006".)
matt at australiangamer dot com
18-Jan-2006 08:32
Regarding the previous post on strtotime() being used to convert mysql datetime strings, I agree that this is not widely realized.

Part of the reason for this is that it is only a relatively recent addition. Prior to PHP 5.0, though it might have been an earlier version, strtotime() would return -1 on a mysql datetime string.

If you're on a server that doesn't have a recent PHP version test your result before assuming this one works.
jeremy at citiesunlimited dot com
12-Jan-2006 01:03
There doesn't seem to be enough documentation about this feature of strtotime(), but it can take a SQL datetime column and convert it to a unix timestamp.

For example:
<?php

$timestamp
= strtotime('2006-01-10 16:09:30');
echo(
$timestamp);

// outputs: 1136930970
?>

This is useful with the Date() Function:
<?php

$timestamp
= strtotime('2006-01-10 16:09:30');
echo
date('n/j/Y g:i:sa', $timestamp);

// outputs: 1/10/2006 4:09:30pm
?>
shaver at qspeed dot com
12-Jan-2006 12:13
I'm posting these here as I believe these to be design changes, not bugs.

For those upgrading from PHP 4 to PHP 5 there are a number of things that are different about strtotime that I have NOT seen documented elsewhere, or at least not as clearly. I confirmed these with two separate fresh installations of PHP 4.4.1 and PHP 5.1.1.

1) Given that today is Tuesday: PHP4 "next tuesday" will return today. PHP5 "next tuesday" will actually return next tuesday as in "today +1week". Note that behavior has NOT changed for "last" and "this". For the string "last tuesday" both PHP4 and PHP5 would return "today -1week".  For the string "this tuesday" both PHP4 and PHP5 would return "today".

2) You cannot include a space immediately following a + or - in PHP 5. In PHP4 the string "today + 1 week" works great. in PHP5 the string must be "today +1 week" to correctly parse.

3) (Partially noted in changelog.) If you pass php4 a string that is a mess ("asdf1234") it will return -1. If you in turn pass this to date() you'll get a warning like: Windows does not support dates prior to midnight. This is pretty useful for catching errors in your scripts. In PHP 5 strtotime will return FALSE which causes date() to return 12/31/69. Note that this is true of strings that might appear right such as "two weeks".

4) (Partially noted in changelog.) If you pass php4 an empty string it will error out with a "Notice: strtotime(): Called with empty time parameter". PHP5 will give no notice and return the current date stamp. (A much preferred behavior IMO.)

5) Some uppercase and mixed-case strings no longer parse correctly. In php4 "Yesterday" would parse correctly. In php5 "Yesterday" will return the infamous 1969 date. This is also true of Tomorrow and Today.

6. The keyword "previous" is supported in PHP5. (Finally!)

Good luck with your upgrades. :)
 -Will
Mr Obvious
10-Jan-2006 10:10
@ nick at fortawesome dot co dot uk
regarding 'month' vs 'next month'

Not sure what version of PHP you found those results on, however with PHP 4.4.0,
<?PHP
$time1
=strtotime('next month');
$time2=strtotime('month');
?>
produce the exact same result.
dean at earlsoft dot co dot uk
02-Jan-2006 04:40
I have recently had to handle parsing date strings without a year, which broke when the year rolled over.

Assuming the dates will always be in the past, you can use this to fall back to the previous year if the date is too far in the future:

<?php
$data
= strtotime("26 dec");
print
date("r", $data) . "\n";
if (
$data > strtotime("+1 week")) {
  print
"Too far in the future\n";
 
$data = strtotime("-1 year", $data);
}
print
date("r", $data) . "\n";
?>

This outputs:
Tue, 26 Dec 2006 00:00:00 +0000
Too far in the future
Mon, 26 Dec 2005 00:00:00 +0000
rajbirsingh_83 at rediffmail dot com
21-Dec-2005 01:14
To add two timestamps and reflect thier effect on the date.

code:-

$t =strtotime('+1 hours 50 min 50 second',strtotime("2005-12-21 23:10:15"));
$result = date("Y-m-d H:i:s",$t);
echo $result;

Rajbir
16-Dec-2005 09:31
Note that by default strtotime( ) considers the string time like a local time.
If your input string time is GMT/UTC do :

<?php
   $date
= '2005-12-25 00:56:27 GMT' ; // Note the timezone specification
  
$time = strtotime($date) ;
   echo
date('d/m/Y H:i:s', $time) ; // $date will be correctly localized
   //  25/12/2005 01:56:27  for France
?>
ScottB
15-Dec-2005 05:36
strtotime assumes a US-style date in the format mm/dd/yy.  This function assumes a UK-style dd/mm/yy format, converts it to US-style and passes it to strtotime.

The date parts can be separated with slashes, hypens, dots or spaces.  Unambiguous dates such as "2005-05-04" or "4 May 05" pass through unaltered (they don't match the regex).

// Returns a timestamp from a string.  Assumes en_GB format where ambiguous.
function parsedate($value)
{
   // If it looks like a UK date dd/mm/yy, reformat to US date mm/dd/yy so strtotime can parse it.
   $reformatted = preg_replace("/^\s*([0-9]{1,2})[\/\. -]+([0-9]{1,2})[\/\. -]+([0-9]{1,4})/", "\\2/\\1/\\3", $value);
   return strtotime($reformatted);
}

e.g.
parsedate("13/11/05"); // 13th November, UK-style
parsedate("4/5/05"); // 4th May not 5th April
parsedate("13 nov 05"); // Unambiguous
parsedate("2005-11-13"); // Unambiguous
heinemann dot juergen at t-online dot de
10-Dec-2005 07:20
An Example to use strtotime for calculat all days from weeks of this month
<?php
function DaysFromMonth( $t )
{
  
// NOTE strtotime only works with english time format
  
setlocale( LC_TIME, "en" );
  
$s = mktime( 0, 0, 0, date( "m", $t ), 1, date( "Y", $t ) );
  
$e mktime( 0, 0, 0, date( "m", $t ), date( "t", $t ), date( "Y", $t ) );
  
// getting days from last month with strtotime at first week
  
$f = strtotime( "-" . ( strftime( "%u", $s ) - 1 ) . " day", $s );
  
// getting days from next month with strtotime at last week
  
$l = strtotime( "+" . ( 7 - strftime( "%u", $e ) ) . " day", $e );
  
$a = array();
   foreach(
range( $f, $l, 86400 ) AS $w ) {
    
$a[date( "W", $w )][ strftime( "%u", $w ) ] = $w;
   }
   return
$a;
}

function
ConvertTime( &$i, $k ) {
  
setlocale( LC_TIME, "de_DE" );
  
$i = strftime( "%A %e, %B %Y", $i );
}

echo
"<dl>";
foreach(
DaysFromMonth( mktime() ) AS $k => $v ) {
  
array_walk( $v, 'ConvertTime' );
   echo
"<dt>Woche:" . $k . "</dt><dd>" . implode( "</dd><dd>", $v ) . "</dd>";
}
echo
"</dl>";
?>
j dot parree at team-networks dot de
06-Dec-2005 09:21
In PHP 4.3.10(Suse Linux 9.2) strtotime() seems to sometimes resolve incorrect month values.
e.g.:
<?
   $day
= strftime ("%d", strtotime("-$day days"));
  
$month = strftime ("%m", strtotime("-$day days"));
  
$year = strftime ("%Y", strtotime("-$day days"));
?>
Result: $month is sometimes: expected month-1

php.net bug-reporting systems says: "problem will be fixed in php5 not any londer in php4!".

Workarround in php4 to savely get the correct values for example above:

<?
   $date
= strftime ("%d.%m.%Y", strtotime("-$day days"));
   list(
$day, $month, $year) = split('[/.]', $date);
?>
cbueno81[nospam]yahoo.com.br
16-Nov-2005 11:51
Criando uma lista com um intervalo de horas de forma dinmica.

Creating a time interval of a dynamic way.

<?php
$basetime
= strtotime("06:00:00");
echo
"<select name='timeinterval'>\n";
for (
$i=0; $i<=34; $i++) {
  echo
"<option value='".date("H:i:s", $basetime)."'>".date("H:i", $basetime)."</option>\n";
 
$time = strtotime("30 minutes", $basetime);
 
$basetime = strtotime(date("H:i:s", $time));
}
echo
"</select>\n";
?>
Nathan
26-Oct-2005 10:03
The pluralization of "minute" or "minutes" for instance does not matter. In case you are dynamically using this function "+1 minutes" or "+2 minute" both do work.
nick at fortawesome dot co dot uk
26-Oct-2005 06:52
Note that strtotime('next month') will return 2 months from now, which may not be what you expect. strtotime('month') will do 1 month.
MonstersAndCritics.com
22-Oct-2005 06:11
Hi,

a simple function which returns the desired interval around the given timestamp as an array with the elements 'to' and 'from'. Possible intervals are: "minute", "hour", "day", "week", "month", "year". If the requested interval is "week", you can additionally provide the first_day_of_week.
<?php

  
function time_to_interval($timestamp, $interval, $first_day_of_week="Sunday")
   {
      
$interval_array = array();
      
$interval_array['from'] = $timestamp;
      
$interval_array['to'] = $timestamp;
      
       switch (
$interval)
       {
           case
"minute" :
              
$from = date("Y-m-d H:i:00", $timestamp);
              
$to = date("Y-m-d H:i:00", strtotime($from . " + 1 minute"));
               break;

           case
"hour" :
              
$from = date("Y-m-d H:00:00", $timestamp);
              
$to = date("Y-m-d H:00:00", strtotime($from . " + 1 hour"));
               break;
          
           case
"day" :
              
$from = date("Y-m-d 00:00:00", $timestamp);
              
$to = date("Y-m-d 00:00:00", strtotime($from . " + 1 day"));
               break;
          
           case
"week" :
              
$to = date("Y-m-d 00:00:00", strtotime("this $first_day_of_week", $timestamp));
              
$from = date("Y-m-d 00:00:00", strtotime("last $first_day_of_week", $timestamp));
               break;
          
           case
"month" :
              
$from = date("Y-m-01 00:00:00",$timestamp);
              
$to = date("Y-m-01 00:00:00", strtotime($from . " + 1 month"));
               break;
          
           case
"year" :
              
$from = date("Y-01-01 00:00:00", $timestamp);
              
$to = date("Y-01-01 00:00:00", strtotime($from . " + 1 year"));
               break;
       }

      
$interval_array['from'] = strtotime($from);
      
$interval_array['to'] = strtotime($to);
       return
$interval_array;
   }

# Use it like :
$timestamp = time();
$interval = time_to_interval($timestamp, "hour");
if (
$mytime >= $interval['from'] && $mytime < $interval['to']){
// do something
}

?>
22-Oct-2005 02:00
In Leftward Shift's message, the strtotime function is not malfunctioning, the code is proper, the results are as expected providing you understand that varialbes will not be escaped (Replaced) from an inline single quote string.
(i.e. <?php 'next $weekday' ?> will be absolutely 'next $weekday' resulting in strtotime returning 0, and $now (Something other than 0) will always be greater than zero)

Either double quote it or put the weekday afterwards --
<?php
$Time
= strtotime('next ' . $weekday, $Time);
?>
Leftward Shift, My Wayward Carry
12-Oct-2005 12:08
I had a partially-written PHP app I started on v4.2.*, and it relied on the pecular behavior of the 'next' keyword in strtotime(). But, when I upgraded to 4.4.0, certain pages caused apache to spin out of control (i.e, 90%+ CPU usage!) This is because the 'next' keyword behaves differently in versions after 4.3.0 (or perhaps even previous versions, see the changelog:
http://www.php.net/ChangeLog-4.php for more info.) I was testing in a while loop like so:

$weekday = "...some arbitrary weekday...";
$now = strtotime('now');
$prevtime = strtotime( ... some random past date ... );
while ($prevtime < $now) {
  ..do stuff..
  ..more stuff..
  $prevtime = strtotime('next $weekday', $prevtime);
}

that used to work, since 'next' would just add a week to $prevtime, but as of 4.3.0 (or perhaps the late 4.2.* series) next no longer works in this way, and this would cause an infinite loop to occur.

Instead, use '+1 week': in the above example, the last line inside the loop should be:
  $prevtime = strtotime('+1 week',$prevtime);

Just though I'd leave a note here if anyone else comes with the same problem!
Jake
11-Oct-2005 09:31
In case anyone is curious, it seems the date output:

date("l dS of F Y h:i:s A")

Is not parsable by strtotime. I wrote this to accomodate.

<?php

function strtotime_oddformat($datestring)
{
      
$datepieces = explode(" ", $datestring);
      
$newdatestring=$datepieces[1]{0}.$datepieces[1]{1}." ".$datepieces[3]." ".$datepieces[4]." ".$datepieces[5]." ".strtolower($datepieces[6]);
       return(
strtotime($newdatestring));
}

?>
saverio dot caminiti at alfanet dot it
10-Oct-2005 04:08
This function is really useful.
But it always returns the minimum timestamp that match the input string. It should be even more useful to have a function strtointerval that return a two timestamps: the minimum timestamp that match the input and the maximum one.
For example:
- strtointerval(Dec 3 2004) should returns a minimum timestamp (0:0:0 Dec 3 2004) and a maximum one (23:59:59 Dec 3 2004).
- strtointerval(Dec 2004) returns 0:0:0 Dec 1 2004 and 23:59:59 Dec 31 2004
- strtointerval(2004) returns 0:0:0 Jan 1 2004 and 23:59:59 Dec 31 2004
And so on.

It should be also useful that strtointerval() parse English sentences like between A and B or [form] A to B where A and B are two valid input for the actual strtotime().

Starting from the source code of strtotime() it should be not difficult to implement strtointerval(), perhaps through a function strtoMAXtime() that generate the maximum timestamp instead of the minimum one, and then adding the English interval sentences support.

Thanks,
Saverio Caminiti.
Rob Allen
06-Oct-2005 05:34
Note strtotime() in PHP 4 does not support fractional seconds.

See http://bugs.php.net/bug.php?id=28717 especially if you happen to swap to ODBC for MS SQL Server and wonder what's happened!
Philippe Jausions -at- 11abacus.com
28-Sep-2005 11:55
The PHP 5.1.0 change is a major backward compatibility break.

Now, that the returned value on failure has changed, the correct way to detect problems on all PHP versions is:

<?php

if (($time = strtotime($date)) == -1 || $time === false) {
   die
'Invalid date';
}

?>

[red (derick): note, this is not 100% correct, as in this case 1969-12-31 23:59 will be thrown out as that timestamp is "-1"]
sholland at napervillegi dot com
29-Aug-2005 09:25
One behavior to be aware of is that if you have "/" in the date then strtotime will believe the last number is the year, while if you use a "-" then the first number is the year.

12/4/03 will be evaluated to the same time as 03-12-4.

This is in the gnu documentation linked to in the article.  I confirmed the behavior with strtotime and getdate.

Steve Holland
codepanda at yahoo dot com
24-Aug-2005 07:29
Building on OJW's comment concerning "stacking" the strtotime function to produce some quite useful results, I wrote this function to calculate the dates of various holidays commonly recognized in the US... it may not be elegant, there may be a better way, but it gets the job done

this was tested on PHP 4.4.0; federally recognized holidays were checked against the list located at http://www.opm.gov/fedhol (covers years 1997-2010, in case the link goes bad), Mardi Gras was checked for years 2003-2024 as found at http://www.mardigrasdigest.com/html/Mardi_Gras_future_dates_100.htm

<?
/* Function  : getHolidays()
** Parameters :
**    $year -- the year in question
** Return    : an associative array containing the holidays occuring in the given year
**    they key is a date stamp of the form Y-m-d, the value is the name of the corresponding holiday
*/
function getHolidays( $year ) {
  
$return = array();
  
  
  
// First off, the simple ones
  
  
$return[$year . '-01-01'] = 'New Year`s Day';
  
$return[$year . '-02-14'] = 'Valentine`s Day';
  
$return[$year . '-06-14'] = 'Flag Day';
  
$return[$year . '-07-04'] = 'Independence Day';
  
$return[$year . '-11-11'] = 'Veteran`s Day';
  
$return[$year . '-12-25'] = 'Christmas';
  
  
  
// and now, the more complex ones
  
   // Martin Luther King, Jr. Day
   // third Monday in January
  
$return[date( 'Y-m-d', strtotime( '2 weeks monday', strtotime( "January 1, $year" ) ) + 43200 )] = 'Martin Luther King, Jr. Day';
  
  
// Presidents` Day
   // third Monday in February
  
$return[date( 'Y-m-d', strtotime( '2 weeks monday', strtotime( "February 1, $year" ) ) + 43200 )] = 'Presidents` Day';
  
  
// Mardi Gras
   // Tuesday ~47 days before Easter
  
$return[date( 'Y-m-d', strtotime( 'last tuesday 46 days ago', easter_date( $year ) ) + 43200 )] = 'Mardi Gras';
  
  
// Easter
   // the Sunday after the first full moon which falls on or after the Spring Equinox
   // thank god PHP has a function for that...
  
$return[date( 'Y-m-d', easter_date( $year ) + 43200 )] = 'Easter';
  
  
// Memorial Day
   // last Monday in May
  
$return[date( 'Y-m-d', strtotime( '-1 week monday', strtotime( "June 1, $year" ) ) + 43200 )] = 'Memorial Day';
  
  
// Labor Day
   // first Monday in September
  
$return[date( 'Y-m-d', strtotime( 'monday', strtotime( "September 1, $year" ) ) + 43200 )] = 'Labor Day';
  
  
// Columbus Day
   // second Monday in October
  
$return[date( 'Y-m-d', strtotime( '1 week monday', strtotime( "October 1, $year" ) ) + 43200 )] = 'Columbus Day';
  
  
// Thanksgiving
   // fourth Thursday in November
  
$return[date( 'Y-m-d', strtotime( '3 weeks thursday', strtotime( "November 1, $year" ) ) + 43200 )] = 'Thanksgiving';
  
  
  
ksort( $return );
   return
$return;
}
?>
tero dot totto at kymp dot net
15-Aug-2005 02:49
When using multiple negative relative items, the result might be a bit unexpected:

<?php
$basedate
= strtotime("15 Aug 2005 10:15:00");
$date1 = strtotime("-1 day 2 hours", $basedate);
$date2 = strtotime("-1 day -2 hours", $basedate);
echo
date("j M Y H:i:s", $date1);  // 14 Aug 2005 12:15:00
echo date("j M Y H:i:s", $date2);  // 14 Aug 2005 08:15:00
?>

The minus sign has to be added to every relative item, otherwise they are interpreted as positive (increase in time). Other possibility is to use "1 day 2 hours ago".
baced2001 at freenet dot de
12-Aug-2005 07:55
if you'd like to create an ip- or cookie-based counter, you've to check the time passed since his last visit.

the first way is to save the current date&time and add the timeout while checking:

<?php
    
function isTimedOut($tsLast, $intTimeoutSecs)
     {
      
$tsTimeout = strtotime("+ " . $intTimeoutSecs . " seconds", $tsLast);
       return (
$tsTimeout < mktime());
     }
     function
TimestampToDBDate($ts)
     {
       return
date("Y-m-d H:i:s", $ts);
     }

    
// $last_visit <-- DB-Entry
    
if (isTimedOut($lastvisit, 60*60*24))
     {
      
// count !!!
      
$last_visit = TimestampToDBDate(mktime());
      
// $last_visit --> DB-Entry
    
}
?>

and the second way is to add the timeout while saving the current time&date:

<?php
    
function CreateTimeoutTimestamp($intTimeoutSecs)
     {
       return
strtotime("+ " . $intTimeoutSecs . " seconds", mktime());
     }
     function
TimestampToDBDate($ts)
     {
       return
date("Y-m-d H:i:s", $ts);
     }

    
// $next_count_date <-- DB-Entry
    
if (mktime() > $next_count_date)
     {
      
// count !!!
      
$next_count_date = TimestampToDBDate(CreateTimeoutTimestamp(60*60*24));
      
// $next_count_date --> DB-Entry
    
}
?>
mjpalm21 at sample5 dot com
04-Aug-2005 05:12
I googled for a Unixtime Gateway and didn't find one - so I poped up this one:

http://sigmatrak.com/sample5/epoch.htm

Stupid simple but handy for me...

:-)
faress at NOSPAMMING dot PLEASE dot gmail dot com
29-Jul-2005 03:49
This is an quick correction to  ldbkutty at yahoo dot com
12-Apr-2005 06:21

he was trying to find a function that will let him add months to a date.

- tried
$myDate = strtotime("+1 month",mktime(0,0,0,1,31,2004));

This returns 2004-03-02 but I wanted the result as 2004-02-29. So, I noticed there is no equivalent function like setLenient as false and he wrote one that I corrected a bit because my installation did not have the cal_days_in_month() function (I used the date('t', $timestamp) to get the days in months for a particular year) .

Hope this helps someone.

<?php

function addMonthNoLenient($my_date, $add_month)
{
  
$mid_month = 15 ;
  
  
$day = date( "d", $my_date );
  
$month = date( "m", $my_date );
  
$year = date( "Y", $my_date );
  
$hour = date( "H", $my_date );
  
$minute = date( "i", $my_date );
  
$second = date( "s", $my_date );
  
  
$new_date_timestamp = mktime( $hour, $minute, $second, $month + $add_month, $day, $year);
  
  
$month_for_days = ( $month + $add_month ) % 12;
   if(
$month_for_days == 0 )
      
$month_for_days = 12;
  
   if(
$month_for_days != date( "m", mktime( $hour, $minute, $second, $month + $add_month , $day, $year ) ) )
   {
      
$new_year = date( "Y", mktime( $hour, $minute, $second, $month + $add_month, $day, $year ) );
      
$days_in_month = date('t', mktime( $hour, $minute, $second, $month_for_days, $mid_month, $new_year ) );
      
$new_date_timestamp = mktime( $hour, $minute, $second, $month + $add_month, $days_in_month, $year );
   }
  
   return
$new_date_timestamp;
}
?>

<?
 
  $your_date
= mktime( 0, 0, 0, 1, 30, 2004 );
 
$months_to_add = 25;
  echo
date( "Y-m-d", addMonthNoLenient( $your_date, $months_to_add ));

?>
sales at chumpstump dot com
28-Jul-2005 10:33
I needed a drop down box so users could see their account balance for the given time period.  Below is a drop box that displays the first of the month for the last twelve months and the value of each is the timestamp of that date.

<?

$time
= time();
$month = date("F");
$year = date("Y");
$string = "1 ";
$string .= $month;
$string .= " ";
$string .= $year;
$first_timestamp = strtotime($string);

$start_box = "<select name='start_date' size='1'><option>Start Date</option>";
$end_box = "<select name='end_date' size='1'><option>End Date</option>";

for (
$i = 0; $i <= 12; $i++) {

$temp = "-";
$temp .= $i;
$temp .= " month";

$timestamp_first = strtotime($temp, $first_timestamp);
$formatted_first = date("F j, Y", $timestamp_first);

$box .= "\n<option value='";
$box .= $timestamp_first;
$box .= "'>";
$box .= $formatted_first;
$box .= "</option>\n";
}

$start_box .= $box;
$end_box .= $box;
$start_box .= "</select>";
$end_box .= "</select>";

?>

Once submitted it was very easy to pull from the db what you needed between the two timestamps.

I'm sure it could be condensed a bit, but the logic is there.  Hope this helps someone.

GG
dcahhNOSPAM at gmx dot de
15-Jul-2005 05:21
Maybe it saves others from troubles:

if you create a date (i.e. a certain day, like 30.03.2005, for a calendar for example) for which you do not consider the time, when using mktime be sure to set the time of the day to noon:

<?php
   $iTimeStamp
= mktime(12, 0, 0, $iMonth, $iDay, $iYear);
?>

Otherwhise

<?php
  
// For example
  
strtotime('-1 month', $iTimeStamp);
?>

will cause troubles when calculating the relative time. It often is one day or even one month off... After I set the time to noon "strtotime" calculates as expected.

Cheers
Denis
timvw at users dot sourceforge dot net
13-Jul-2005 07:13
relative dates..

echo date('d F Y', strtotime('last monday', strtotime('15 July 2005'))); // 11th
echo "<br>";
echo date('d F Y', strtotime('this monday', strtotime('15 July 2005'))); // 18th
echo "<br>";
echo date('d F Y', strtotime('next monday', strtotime('15 July 2005'))); // 25th
Dan Libby
08-Jul-2005 05:55
This improves on safestrtotime() by returning -1 when the date is before 1902-01-01.  Otherwise it was returning bogus values for older dates.

   function safestrtotime ($s) {
     $basetime = 0;
     if (preg_match ("/(\d\d\d\d)/", $s, $m) && ($m[1] < 1970)) {
         if( $m[1] < 1902 ) {
           return -1;
         }
         $s = preg_replace ("/19\d\d/", $m[1]+68, $s);
         $basetime = 0x80000000 + 1570448;
     }
     $t = strtotime( $s );
     return $t == -1 ? -1 : $basetime + $t;
   }
ruben at wipkip dot com
28-Jun-2005 08:14
This is an easy way to calculate the number of months between 2 dates (including the months in which the dates are themselves).

<?

   $startDate
= mktime(0,0,0, 6, 15, 2005);
  
$stopDate = mktime(0,0,0, 10, 8, 2006);
  
  
$nrmonths = ((idate('Y', $stopDate) * 12) + idate('m', $stopDate)) - ((idate('Y', $startDate) * 12) + idate('m', $startDate));

?>

Results in $nrmonths = 16.
rogier at patsfactor dot nl
20-Jun-2005 09:07
@brett at medeaproject dot co dot za

Slightly offtopic:
It might be easier to select the unix timestamp directly from MySQL, something like "SELECT UNIX_TIMESTAMP( mysqltimestampfield ) AS TIME" should render you little function obsolete.
yasingedikli at hotmail dot com
24-May-2005 08:45
You can get the beginn and end date from weeknumber !

function dateweek($weeknumber)
{
$x = strtotime("last Monday");
$Year = date("Y",$x);
$Month = date("m",$x);
$Day = date("d",$x);
if ($Month < 2 && $Day < 8) {
$Year = $Year--;
$Month = $Month--;
}
if ($Month > 1 && $Day < 8)
$Month = $Month--;
//DATE BEGINN OF THE WEEK ( Monday )
$Day = $Day+7*$weeknumber;
echo date('Y-m-d', mktime(0, 0, 0, $Month, $Day, $Year));
//DATE END OF THE WEEK ( Sunday )
$Day = $Day+6;
echo date('Y-m-d', mktime(0, 0, 0, $Month, $Day, $Year));
}

// THIS WEEK
dateweek(0);

// LAST WEEK
dateweek(-1);

// NEXT WEEK
dateweek(1);

// 4 WEEK THEN
dateweek(4);
Rene Leonhardt (rele at gmx dot de)
11-May-2005 08:48
Here is a slightly improved version of date_uk_to_american, posted by James McGuigan on 27-Dec-2004 08:31.
Now you can use the function to parse a date string (user input) to show, whether it was recognized correctly.

function date_uk_to_american($date, $replace_separator = FALSE) {
  $days  = '0?[1-9]|[12][0-9]|3[01]';
  $months= '0?[1-9]|1[0-2]';
  $year  = '\d{2}|\d{4}';
  $non_alpha = '[^0-9a-zA-Z]+';
  return preg_replace( "/^\s*($days)($non_alpha)($months)($non_alpha)($year)/", $replace_separator === FALSE ? '$3$2$1$4$5' : '$3'.$replace_separator.'$1'.$replace_separator.'$5', $date);
}

function parse_date($date) {
  return date("d.m.Y", strtotime(date_uk_to_american($date, '/')));
}

//example: echo parse_date('3.12.83');
not provided
11-May-2005 08:34
A shorter function for recognising dates before 1970 and returning a negative number is below. All it does is replaces years before 1970 with  ones 68 years later (1904 becomes 1972), and then offsets the return value by a couple billion seconds. It works back to 1/1/1902, but only on dates that have a century.

function safestrtotime ($s) {
       $basetime = 0;
       if (preg_match ("/19(\d\d)/", $s, $m) && ($m[1] < 70)) {
               $s = preg_replace ("/19\d\d/", 1900 + $m[1]+68, $s);
               $basetime = 0x80000000 + 1570448;
       }
       return $basetime + strtotime ($s);
}

Note that a negative number is stored the same as a really big positive number. 0x80000000 is the number of seconds between 13/12/1901 20:45:54 and 1/1/1970 00:00:00. And 1570448 is the seconds between this date and 1/1/1902 00:00:00, which is 68 years before 1/1/1970.
LittleZephyr at nillahood dot net
10-May-2005 04:49
Here's a quick one-line function you can use to get the time difference for relative times. But default, if you put in a relative time (like "1 minute"), you get that relative to the current time. Using this function will give you just the time difference in seconds:

<?php function relative_time( $input ) { return strtotime($input) - time(); } ?>

For example "1 minute" will return 60, while "30 seconds ago" will return -30

Valid relative time formats can be found at http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html#SEC115
Ed Lecky-Thompson
27-Apr-2005 12:04
Here's a quick function which can replace strtotime, and will work fine on dates pre-1970 (i.e. it will return a negative number as expected).

This negative time stamp seems to be supported as an input parameter by methods like date() up to a point, but if you get crazy and start talking about dates in the 1700s (everybody was using PHP3 back then, of course) it gets upset.

For those of you doing staff databases and so forth, of course, this is probably fine - it's definitely OK for any dates post 1900, and this value has been hard coded into the function below.

   function safestrtotime($strInput) {
       $iVal = -1;
       for ($i=1900; $i<=1969; $i++) {
           # Check for this year string in date
           $strYear = (string)$i;
           if (!(strpos($strInput, $strYear)===false)) {
               $replYear = $strYear;
               $yearSkew = 1970 - $i;
               $strInput = str_replace($strYear, "1970", $strInput);
           };
       };
       $iVal = strtotime($strInput);
       if ($yearSkew > 0) {
           $numSecs = (60 * 60 * 24 * 365 * $yearSkew);
           $iVal = $iVal - $numSecs;
           $numLeapYears = 0;        # Work out number of leap years in period
           for ($j=$replYear; $j<=1969; $j++) {
               $thisYear = $j;
               $isLeapYear = false;
               # Is div by 4?
               if (($thisYear % 4) == 0) {
                   $isLeapYear = true;
               };
               # Is div by 100?
               if (($thisYear % 100) == 0) {
                   $isLeapYear = false;
               };
               # Is div by 1000?
               if (($thisYear % 1000) == 0) {
                   $isLeapYear = true;
               };
               if ($isLeapYear == true) {
                   $numLeapYears++;
               };
           };
           $iVal = $iVal - (60 * 60 * 24 * $numLeapYears);
       };
       return($iVal);
   };
websafe at partybitchez dot org
24-Apr-2005 02:53
A small update... Should be ok now.

<?php
function count_months($start_date, $end_date) {
  
# Returns whole-month-count between two dates
   # websafe<at>partybitchez<dot>org
   # usage
   #    count_months("1978-02-18", "2028-08-12");
   #
  
$start_date_unixtimestamp = strtotime($start_date);
  
$start_date_month = date("m", $start_date_unixtimestamp);
  
$end_date_unixtimestamp = strtotime($end_date);
  
$end_date_month = date("m", $end_date_unixtimestamp);
  
$calculated_date_unixtimestamp = $start_date_unixtimestamp;
  
$counter=0;
   while (
$calculated_date_unixtimestamp < $end_date_unixtimestamp)   
   {
      
$counter++;
      
$calculated_date_unixtimestamp = strtotime($start_date . " +{$counter} months");
   }
  
#
  
if ( ($counter==1) && ($end_date_month==$start_date_month)) $counter=($counter-1);
   return
$counter;
}
?>

Example 01: count_months("1996-02-18", "2005-11-24") returns 118
Example 02: count_months("2005-04-24", "2005-04-24") returns 0
Example 03: count_months("2005-04-24", "2005-04-25") returns 0
Example 04: count_months("1978-02-18", "2028-08-12") returns 606
Example 05: count_months("2008-02-29", "2009-02-29") returns 12
Example 06: count_months("2008-02-29", "2008-03-01") returns 1
Example 07: count_months("2008-02-29", "2008-03-02") returns 1
Example 08: count_months("2008-02-29", "2009-02-28") returns 12
Example 09: count_months("2008-02-29", "2009-02-29") (not existing enddate) returns 12
Example 10: count_months("2008-02-29", "2009-03-01") returns 12
Example 11: count_months("2008-02-29", "2009-03-02") returns 13
miamiseb at nospam_gmail dot com
23-Apr-2005 12:59
If you strtotime the epoch (Jan 1 1970 00:00:00) you will usually get a value, rather than the expected 0. So for example, if you were to try to use the epoch to calculate the difference in times (strtotime(Jan 1 1970 21:00:00)-strtotime(Jan 1 1970 20:00:00) for example) You get a value that depends strongly upon your timezone. If you are in EST for example, the epoch is actually shifted -5 to YOUR epoch is Jan 1 1970 19:00:00) In order to get the offset, simply use the following call to report the number of seconds you are away from the unix epoch. $offset=strtotime("1970-01-01 00:00:00"); Additionally, you can append GMT at the end of your strtotime calls so save yourself the trouble of converting relative to timezone.
thraoln at yahoo dot com
17-Apr-2005 07:04
Quick solution to strtotime() function returning wrong results(for PHP4 and below) when it tries to "guess what you meant" and will successfully parse dates that would otherwise be considered invalid...just dont use it, this works better:

function valid_date($thedate) {
   list($year, $month, $day) = sscanf($thedate, "%d-%d-%d");
   return checkdate($month, $day, $year);
}

"2005-11-25" returns TRUE
"2005-11-32" returns FALSE
ldbkutty at yahoo dot com
13-Apr-2005 06:21
I was trying to find a funtion that will let me add months to a date.

I have tried

$myDate = strtotime("+1 month",mktime(0,0,0,1,31,2004));

This returns 2004-03-02 but I wanted the result as 2004-02-29. So, I noticed there is no equilent function like setLenient as false and I wrote one.

Hope this helps for someone.

<?php

function addMonthNoLenient($my_date, $add_month)
{
 
$day = date( "d", $my_date );
 
$month = date( "m", $my_date );
 
$year = date( "Y", $my_date );

 
$new_date = date( "Y-m-d", mktime( 0, 0, 0, $month + $add_month, $day, $year) );

 
$month_for_days = ( $month + $add_month ) % 12;
  if(
$month_for_days == 0 )
  {
  
$month_for_days = 12;
  }

  if(
$month_for_days != date( "m", mktime( 0, 0, 0, $month + $add_month , $day, $year ) ) )
  {
  
$new_year = date( "Y", mktime( 0, 0, 0, $month + $add_month, $day, $year ) );
  
$days_in_month = cal_days_in_month( CAL_GREGORIAN, $month_for_days, $new_year );
  
$new_date = date( "Y-m-d", mktime( 0, 0, 0, $month + $add_month, $days_in_month, $year ) );
  }
  return
$new_date;
}

?>

<?
 
  $your_date
= mktime( 0, 0, 0, 1, 30, 2004 );
 
$months_to_add = 25;
  echo
addMonthNoLenient( $your_date, $months_to_add );

?>
Greg Robbins
08-Apr-2005 04:12
This function will count fractional months between 2 dates, perhaps for billing purposes (like for hosting, as was my case).

<?php
function count_months($start_date, $end_date)
{
  
//Initialize counters for days and months
  
$days = 0;
  
$months = 0;
  
  
//get current month (as of your start_date)
  
$curr_month = date("Y-m-01", $start_date);
  
  
//loop by days
  
while($start_date <= $end_date)
   {
      
//If the current iteration has passed on to a new month
      
if($curr_month != date("Y-m-01", $start_date))
       {
          
//divide the number of days counted by the number of days in the month
           //to get a decimal representation of how many months should be counted.
           //Increment the months count by this value
          
$months += $days / date("t", strtotime($curr_month));
          
          
//Uncomment the following line to see how it counts month by month
           //echo "$days Days / " . date("t", strtotime($curr_month)) . " days in month $curr_month<br>\n";
          
           //Advance the current month
          
$curr_month = date("Y-m-01", strtotime($curr_month . " + 1 months"));
          
          
//Reset the days counter sibce we are now counting a new month
          
$days = 0;
       }
      
      
//Advance tot he next day...
      
$start_date = strtotime(date("Y-m-d", $start_date) . " + 1 days");
      
      
//And increment the day counter
      
$days++;
   }
  
  
//This is the same as above but applied to the last month
  
$months += $days / date("t", strtotime($curr_month));
  
  
//Uncomment the following line to see how it counts month by month
   //echo "$days Days / " . date("t", strtotime($curr_month)) . " days in month $curr_month<br>\n";
  
   //This returns a decimal value to two decimals of accuracy
  
return sprintf("%01.2f", $months);
}

//Check it out:
$last_billed_date = "2004-12-31";
$bill_thru_this_date = "2005-04-15";

$unix_start_date = strtotime($last_billed_date . " +1 days");
$unix_end_date = strtotime($bill_thru_this_date);

echo
"Last billed date: " . $last_billed_date . "<br>";
echo
"Bill through date: " . $bill_thru_this_date . "<br>";
echo
"Total months: " . count_months($unix_start_date, $unix_end_date);
?>
06-Apr-2005 02:45
I ran into the same problem with "last" as gabrielu at hotmail dot com (05-Apr-2005 10:45) when using strtotime() with getdate(). My only guess is that it has to do with daylight savings time as it seemed to be ok for most dates except those near the first Sunday in April and last Sunday in October.

I used strftime() with strtotime() and that gave me the result I was looking for.
gabrielu at hotmail dot com
06-Apr-2005 12:45
While working on an employee schedule application I noticed an issue with using strtotime('last...').  I ran tests on each weekday for each week within a year and noticed inconsistencies while using:

   date('m/d/Y', strtotime('last Wednesday', '2005-04-05'))

Most calculations of the 'last Wednesday' for each week calculated accordingly however I noticed a problem with several dates, one being '04/05/2005' (April 5th 2005).

   date('m/d/Y', strtotime('last Wednesday', '2005-04-05'))

The above should have returned '03/30/2005'.  Instead, it returned '03/29/2005'.  I don't understand why the function is returning this value.  Regardless, my solution:

   date('m/d/Y', strtotime('-1 week' ,strtotime('Wednesday', '2005-04-05')))
insta at citiesunlimited dot com
02-Apr-2005 06:56
Just a note ... there cannot be spaces between the + and the amount you want to add.

strtotime("{$myDate} -1 months") is correct.
strtotime("{$myDate} - 1 months") is not.

Caused me a headache ...
dfuchs at donotspam dot gmail dot com
30-Mar-2005 06:15
Just pointing out that date( 'M', strtotime( 'last month', [some timestamp]) ) will not actually give the name of the previous month if the day of [some timestamp] doesn't exsist in the previous month.  It will instead round up, and give the name of one month AFTER the previous month ('this month', that is). 

For example date( 'M', strtotime( 'last month', [March 31st]) ) will return 'Mar'. 

This is documented here: http://www.gnu.org/software/tar/manual/html_chapter/tar_7.html (also linked from this manual page), but is not easy to find:

" The fuzz in units can cause problems with relative items. For example, `2003-07-31 -1 month' might evaluate to 2003-07-01, because 2003-06-31 is an invalid date. To determine the previous month more reliably, you can ask for the month before the 15th of the current month. For example:

$ date -R
Thu, 31 Jul 2003 13:02:39 -0700
$ date --date='-1 month' +'Last month was %B?'
Last month was July?
$ date --date="$(date +%Y-%m-15) -1 month" +'Last month was %B!'
Last month was June! "

Hope that helps somebody!
farooqym at ieee dot org
23-Feb-2005 12:12
This function will return an array containing the months between two dates:

function get_months ( $start, $end ) {

   while ( strtotime($start) <= strtotime($end) ) {
       $months[] = date("F, Y", strtotime( "$start" ) );
       $start = date("Y-m-d", strtotime( "$start + 1 months")) ;   
   }
   return $months;
}
ssettl2 at gee mail dot com
14-Jan-2005 05:09
Needed a way to query mysql and find things occuring in the most recently completed workweek.

<?
$last_friday
= date("Y-m-d 00:00:00",strtotime("last Friday"));
$last_monday = date("Y-m-d 23:59:59",strtotime("last Monday",strtotime($last_friday)));
?>

Now I just compare these dates with dates in my table.
phpnotes at majiclab dot com
17-Dec-2004 10:10
If anyone is stuck with PHP5 version <5.0.3, and needs to use strtotime functions:

<?php
function strtotimefix($strtotime)
{
   return
time() + (strtotime($strtotime) - strtotime('now'));
}

strtotime('+10 seconds'); // will not work as expected
strtotimefix('+10 seconds'); // should work as expected
?>
bishop
09-Dec-2004 12:12
Be warned that strtotime() tries to "guess what you meant" and will successfully parse dates that would otherwise be considered invalid:

<?php

$ts
= strtotime('1999-11-40');
echo
date('Y-m-d', $ts);

// outputs: 1999-12-10

?>

It is my understanding (I have not verified) that the lexer for strtotime() has been rewritten for PHP5, so these semantics may only apply for PHP4 and below.
Dot_Whut?
06-Dec-2004 06:47
I'm not so sure the following claim (taken from above) is true in all cases:

$date_time2 = strtotime("2004-04-04 02:00:00 GMT"); // works great!

When I try this (on a server that acknowledges Pacific Daylight Savings Time):

echo date('Y-m-d H:i:s'. $date_time2);

I get:

2004-04-03 17:00:00

which is incorrect.  It should be 18:00 hours, the day prior.  It would appear that although GMT (or UTC or even Z) is specified in the time string, the date is treated as if a Daylight Savings Time switch should apply when it shouldn't.

Try this (only if your server would acknowledge PST/PDT in North America)...

// In Greenwich (UTC) at 2:00 AM on the first Sunday in April,
// it is NOT Daylight Savings Time ANYWHERE in North America
$std_time = strtotime('2004-04-04 01:59:59 UTC');
$std_time = strtotime('2004-04-04 02:00:00 UTC');

echo 'Standard Time: ' . date('Y-m-d H:i:s', $std_time) . '<br />';
echo 'Daylight Savings: ' . date('Y-m-d H:i:s', $dst_time) . '<br />';

Emits:

Standard Time: 2004-04-03 17:59:59
Daylight Savings: 2004-04-03 17:00:00

Which is totally incorrect.  Why does should the clock "fall" backward anyways?  I thought the rule was "spring" forward.

The following example does work properly as expected:

// In Greenwich (UTC) at 10:00 AM on the first Sunday in April,
// it is Daylight Savings Time in most of North America
// For Mountain 08:59, Central 07:59, Eastern 06:59, Atlantic 05:59
$std_time = strtotime('2004-04-04 09:59:59 UTC');
// For Mountain 9:00, Central 08:00, Eastern 07:00, Atlantic 06:00
$dst_time = strtotime('2004-04-04 10:00:00 UTC');

echo 'Standard Time: ' . date('Y-m-d H:i:s', $std_time) . '<br />';
echo 'Daylight Savings: ' . date('Y-m-d H:i:s', $dst_time) . '<br />';

Which emits:

Standard Time: 2004-04-04 01:59:59
Daylight Savings: 2004-04-04 03:00:00

Which is correct...
matt at farleyfamily dot net
21-Oct-2004 12:05
Here's a good way to find the next X Weekday of the month (ie the next 3rd Tuesday of the month)

<?
  
# set nextmtg to 3rd tuesday after the first of the month
  
$nextMeeting = strtotime("+2 week Tuesday", strtotime("first ".date("F"))) + 43200;

  
# if nextmtg is past, set it to 3rd tuesday after first of next month
  
if ($nextMeeting < time())
      
$nextMeeting = strtotime("+2 week Tuesday", strtotime("first ".date("F",strtotime("month")))) + 43200;
      
  
$nextMeeting = date("F dS, Y", $nextMeeting);
   echo
"    <p>&radic; <strong>$nextMeeting</strong></p>";
?>
maxz /* at */ rdtc /* dot */ ru
17-Sep-2004 06:52
When you convert date string got by untrusted source (such as If-Modified-Since HTTP Header) don't forget to check if the date string is empty.
<? strtotime('') ?>
returns current timestamp on my php 4.3.8
tim at komta dot com
20-Aug-2004 09:38
After a slight moment of frustration, and finding that I'm not the only one with this problem (see http://bugs.php.net/bug.php?id=28088 - it's a known bug) I decided to write a short workaround for dealing with the 00 hour problem.

The problem only seems to occur when inputting strings such as '08/20/2004 0047' and NOT '08/20/2004 00:47'.  Hence, my fix:

<?php
$your_value
( preg_replace ('#^(\d+/\d+/?\d{2,4} )(00)(\d{2})$#', '$1$2:$3', $your_value() ));
?>
OJW
28-Jun-2004 02:06
I believe these functions can be "stacked" to produce some quite useful results.  For example, the following code gives you the last Monday in August (a UK bank holiday)

<?php
   $LastMondayAugust
= strtotime("-1 week monday", strtotime("1 september 2004")) + 43200;
?>

"-1 week" gives you the week before 1 september
"monday" increases the day until it's a monday
43200 is 12 hours in seconds (if you use dates at midnight, a timezone change will occasionally put you one hour into the wrong day)
php at bucksvsbytes dot com
23-Jun-2004 07:15
strtotime (in PHP 4.2.2 anyway) doesn't seem to support fractional seconds, even though the underlying GNU routines document them. Example:
<?php strtotime('2004-06-13 09:20:00.0') ?> returns "12/31/69, 06:59:59" (INCORRECT due to decimal seconds)
<?php strtotime('2004-06-13 09:20:00') ?> returns "6/13/04, 09:20:00" (CORRECT, no decimal seconds)
cryogen at mac dot com
07-Apr-2004 02:39
I neglected to include the solution in my last post for using strtotime() with date-time data stored in GMT.  Append the string "GMT" to all of your datetimes pulled from MySQL or other database that store date-times in the format "yyyy-mm-dd hh:ii:ss" just prior to converting them to a unix timestamp with strtotime().  This will ensure you get a valid GMT result for times during daylight savings.

EXAMPLE:
<?php
$date_time1
= strtotime("2004-04-04 02:00:00"); // returns bad value -1 due to DST
$date_time2 = strtotime("2004-04-04 02:00:00 GMT"); // works great!
?>
cryogen at mac dot com
07-Apr-2004 01:42
It appears that the strtotime() function returns a value of "-1" for the hour that is skipped during the summer daylight savings time (2:00 am on first Sunday of April).  For example if you enter the following:

<?php
$new_dt
= strtotime("2004-04-04 02:00:00");
if (
$new_dt == -1) echo "Could not convert date-time!";
echo
date("m/d/Y H:i:s", $new_dt);
?>
will print:
-----------
Could not convert date-time
12/31/1969 15:59:59

Any time between 02:00:00 and 2:59:59, which is the hour we "spring forward", strtotime() will produce the bad result.  This is NOT true for the "fall back" on the last Sunday of October at 2:00 am when the clocks are set back an hour, which produces a correct result. This can cause problems if you are storing dates in GMT time, for example, in your database, and need to convert them to a unix timestamp for calculations in your PHP scripts.  GMT time does not change during daylight savings time.
kiscix at hotmail dot com
06-Apr-2004 01:37
Sometime due to Timezone,
strtotime('last sunday') will return the last saturday.

To be sure that will never happen, use strtotime('last sunday 12:00:00')
kyle at frozenonline dot com
02-Jan-2004 07:24
I was having trouble parsing Apache log files that consisted of a time entry (denoted by %t for Apache configuration). An example Apache-date looks like: [21/Dec/2003:00:52:39 -0500]

Apache claims this to be a 'standard english format' time. strtotime() feels otherwise.

I came up with this function to assist in parsing this peculiar format.

<?php
function from_apachedate($date)
{
       list(
$d, $M, $y, $h, $m, $s, $z) = sscanf($date, "[%2d/%3s/%4d:%2d:%2d:%2d %5s]");
       return
strtotime("$d $M $y $h:$m:$s $z");
}
?>

Hope it helps anyone else seeking such a conversion.