date

(PHP 3, PHP 4, PHP 5)

date -- 格式化一个本地时间/日期

说明

string date ( string format [, int timestamp] )

返回将整数 timestamp 按照给定的格式字串而产生的字符串。如果没有给出时间戳则使用本地当前时间。换句话说,timestamp 是可选的,默认值为 time()

提示: 自 PHP 5.1.0 起有几个有用的常量可用作标准的日期/时间格式来指定 format 参数。

注: 有效的时间戳典型范围是格林威治时间 1901 年 12 月 13 日 20:45:54 到 2038 年 1 月 19 日 03:14:07。(此范围符合 32 位有符号整数的最小值和最大值)。不过在 PHP 5.1 之前此范围在某些系统(如 Windows)中限制为从 1970 年 1 月 1 日到 2038 年 1 月 19 日。

注: 要将字符串表达的时间转换成时间戳,应该使用 strtotime()。此外一些数据库有一些函数将其时间格式转换成时间戳(例如 MySQL 的 UNIX_TIMESTAMP 函数)。

表格 1. 格式字串可以识别以下 format 参数的字符串

format 字符说明返回值例子
------
d月份中的第几天,有前导零的 2 位数字0131
D星期中的第几天,文本表示,3 个字母MonSun
j月份中的第几天,没有前导零131
l(“L”的小写字母)星期几,完整的文本格式SundaySaturday
NISO-8601 格式数字表示的星期中的第几天(PHP 5.1.0 新加)1(表示星期一)到 7(表示星期天)
S每月天数后面的英文后缀,2 个字符stndrd 或者 th。可以和 j 一起用
w星期中的第几天,数字表示0(表示星期天)到 6(表示星期六)
z年份中的第几天0366
星期------
WISO-8601 格式年份中的第几周,每周从星期一开始(PHP 4.1.0 新加的)例如:42(当年的第 42 周)
------
F月份,完整的文本格式,例如 January 或者 MarchJanuaryDecember
m数字表示的月份,有前导零0112
M三个字母缩写表示的月份JanDec
n数字表示的月份,没有前导零112
t给定月份所应有的天数2831
------
L是否为闰年如果是闰年为 1,否则为 0
oISO-8601 格式年份数字。这和 Y 的值相同,只除了如果 ISO 的星期数(W)属于前一年或下一年,则用那一年。(PHP 5.1.0 新加)Examples: 1999 or 2003
Y4 位数字完整表示的年份例如:19992003
y2 位数字表示的年份例如:9903
时间------
a小写的上午和下午值ampm
A大写的上午和下午值AMPM
BSwatch Internet 标准时000999
g小时,12 小时格式,没有前导零112
G小时,24 小时格式,没有前导零023
h小时,12 小时格式,有前导零0112
H小时,24 小时格式,有前导零0023
i有前导零的分钟数0059>
s秒数,有前导零0059>
时区------
e时区标识(PHP 5.1.0 新加)例如:UTCGMTAtlantic/Azores
I是否为夏令时如果是夏令时为 1,否则为 0
O与格林威治时间相差的小时数例如:+0200
T本机所在的时区例如:ESTMDT(【译者注】在 Windows 下为完整文本格式,例如“Eastern Standard Time”,中文版会显示“中国标准时间”)。
Z时差偏移量的秒数。UTC 西边的时区偏移量总是负的,UTC 东边的时区偏移量总是正的。-4320043200
完整的日期/时间------
cISO 8601 格式的日期(PHP 5 新加)2004-02-12T15:19:21+00:00
rRFC 822 格式的日期例如:Thu, 21 Dec 2000 16:01:07 +0200
U从 Unix 纪元(January 1 1970 00:00:00 GMT)开始至今的秒数参见 time()

格式字串中不能被识别的字符将原样显示。Z 格式在使用 gmdate() 时总是返回 0

例子 1. date() 例子

<?php
// 设定要用的默认时区。自 PHP 5.1 可用
date_default_timezone_set('UTC');


// 输出类似:Monday
echo date("l");

// 输出类似:Monday 15th of August 2005 03:12:46 PM
echo date('l dS \of F Y h:i:s A');

// 输出:July 1, 2000 is on a Saturday
echo "July 1, 2000 is on a " . date("l", mktime(0, 0, 0, 7, 1, 2000));

/* 在格式参数中使用常量 */
// 输出类似:Mon, 15 Aug 2005 15:12:46 UTC
echo date(DATE_RFC822);

// 输出类似:2000-07-01T00:00:00+0000
echo date(DATE_ATOM, mktime(0, 0, 0, 7, 1, 2000));
?>

在格式字串中的字符前加上反斜线来转义可以避免它被按照上表解释。如果加上反斜线后的字符本身就是一个特殊序列,那还要转义反斜线。

例子 2. 在 date() 中转义字符

<?php
// prints something like: Wednesday the 15th
echo date("l \\t\h\e jS");
?>

可以把 date()mktime() 结合使用来得到未来或过去的日期。

例子 3. date()mktime() 例子

<?php
$tomorrow  
= mktime(0, 0, 0, date("m")  , date("d")+1, date("Y"));
$lastmonth = mktime(0, 0, 0, date("m")-1, date("d"),   date("Y"));
$nextyear  = mktime(0, 0, 0, date("m"),   date("d"),   date("Y")+1);
?>

注: 由于夏令时的缘故,这种方法比简单地在时间戳上加减一天或者一个月的秒数更可靠。

一些使用 date() 格式化日期的例子。注意要转义所有其它的字符,因为目前有特殊含义的字符会产生不需要的结果,而其余字符在 PHP 将来的版本中可能会被用上。当转义时,注意用单引号以避免类似 \n 的字符变成了换行符。

例子 4. date() 格式举例

<?php
// 假定今天是:March 10th, 2001, 5:16:18 pm
$today = date("F j, Y, g:i a");                 // March 10, 2001, 5:16 pm
$today = date("m.d.y");                         // 03.10.01
$today = date("j, n, Y");                       // 10, 3, 2001
$today = date("Ymd");                           // 20010310
$today = date('h-i-s, j-m-y, it is w Day z ');  // 05-16-17, 10-03-01, 1631 1618 6 Fripm01
$today = date('\i\t \i\s \t\h\e jS \d\a\y.');   // It is the 10th day.
$today = date("D M j G:i:s T Y");               // Sat Mar 10 15:16:08 MST 2001
$today = date('H:m:s \m \i\s\ \m\o\n\t\h');     // 17:03:17 m is month
$today = date("H:i:s");                         // 17:16:17
?>

要格式化其它语种的日期,应该用 setlocale()strftime() 函数。

参见 getlastmod()gmdate()mktime()strftime()time()


add a note add a note User Contributed Notes
Lionel
26-Oct-2006 04:38
my quick and dirty code to find the season of the current date

<?php
function season() {
  
$limits=array('/12/21'=>'Winter', '/09/21'=>'Autumn', '/06/21'=>'Summer', '/03/21'=>'Spring', '/01/01'=>'Winter');
   foreach (
$limits AS $key => $value) {
      
$limit=date("Y").$key;
       if (
strtotime($adate)>=strtotime($limit)) {
           return
$value;
       }
   }
}
echo
season();
?>

PS: the 21th is a good approach but not the real day.
lcapt at dplanet dot ch
26-Oct-2006 03:44
my quick and dirty code to find the season of the date

<?php
function season() {
  
$limits=array('/12/21'=>'Winter','/09/21'=>'Autumn',
'/06/21'=>'Summer','/03/21'=>'Spring','/12/31'=>'Winter');
   foreach (
$limits AS $key => $value) {
      
$limit=date("Y").$key;
       if (
strtotime("now")>strtotime($limit)) {
           return
$value;
       }
   }
}
echo
season();
?>

PS: the 21th is a good approach but not the real day.
admin [at] xorath [dot] com
23-Oct-2006 11:13
If you want to use the date function to fix the RFC-822 format from an allready made RSS 2.0 feed you can do it like this..

Maybe getting an external feed from another asp or php file that you cannot change, but want to have the correct dateformat for anyway.

<?php
   header
('Content-type: application/rss+xml; charset=iso-8859-1');
  
$xmlfile = simplexml_load_file($_GET[feedURL]);
   for (
$i = 0; $i < count($xmlfile->channel->item); $i++ )
      
$xmlfile->channel->item[$i]->pubDate = date("r",strtotime((string)($xmlfile->channel->item[$i]->pubDate)));
   echo
$xmlfile->asXML();
?>

Then simply link to your rss feed like this
filename.php?feedURL=http://www.example.com/rss.asp
filename.php?feedURL=http://www.example.com/rss.xml
filename.php?feedURL=http://www.example.com/rss.php

or what you want. Hope anyone can take advantage of this, I wrote it to help a friend which had date stored in database only by yyyy-mm-dd hh:mm:ss and retrieved via asp from another script.

Article at http://www.xorath.com/articles/?article=2
emailfire at gmail dot com
08-Oct-2006 12:39
To use the date("N") function in PHP < 5.1.0 use:

<?php
function dayofweek() {
$days = array("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
return
array_search(date("D"), $days) + 1;
}
?>
Mushy
30-Sep-2006 10:17
Heres a basic print out of a calender:

<?
$date_month
= 7;
$date_year = 2006;

$theday = date(w, mktime(0, 0, 0, $date_month, 1, $date_year));
$daysinmonth = date("t", mktime(0, 0, 0, $date_month, 1, $date_year));
echo
"<table border=1>";
echo
"<tr>";
echo
"<td>Sunday</td>";
echo
"<td>Monday</td>";
echo
"<td>Tuesday</td>";
echo
"<td>Wednesday</td>";
echo
"<td>Thursday</td>";
echo
"<td>Friday</td>";
echo
"<td>Saturday</td>";
echo
"</tr>";
echo
"<tr>";
for (
$i=0;$i<$theday;$i++)
{
   echo
"<td>&nbsp;</td>";
}
for (
$list_day=1;$list_day<=$daysinmonth;$list_day++)
{

   echo
"<td>" . $list_day . "</td>";

   if (
$theday == 6)
   {
       echo
"</tr>";
       echo
"<tr>";
      
$theday = -1;
   }
  
$theday++;
}
echo
"</tr>";
echo
"</table>";
?>
Michiel
28-Sep-2006 11:08
If you want to count quarters between dates you can use the following:

function countQuarters($begindate, $enddate)
       {
           if (!isset($begindate) || empty($begindate) || !isset($enddate) || empty($enddate))
               return -1;
          
           $countyears = date("Y", strtotime($enddate)) - date("Y", strtotime($begindate));
           $quarters = 0;
          
           if (date("Y", strtotime($enddate)) == date("Y", strtotime($begindate)))
           {
               if (date("m", strtotime($enddate)) != date("m", strtotime($begindate)))
               {
                   if (date("m", strtotime($enddate)) > date("m", strtotime($begindate)))
                   {
                       $difference = date("m", strtotime($enddate)) - date("m", strtotime($begindate));
                      
                       $quarters += ceil((int) $difference / 4);
                   }
                   else
                   {
                       return -1;
                   }
               }
           }
           else
           {
               $quarters = (int) $countyears * 4;
               if (date("m", strtotime($enddate)) != date("m", strtotime($begindate)))
               {
                   if (date("m", strtotime($enddate)) > date("m", strtotime($begindate)))
                   {
                       $difference = date("m", strtotime($enddate)) - date("m", strtotime($begindate));
                      
                       $quarters += ceil((int) $difference / 4);
                   }
                   else
                   {
                       $afterbegin = 12 - (int) date("m", strtotime($begindate));
                       $untilend = date("m", strtotime($enddate));
                      
                       $quarters = ($quarters - 4) + ceil(($afterbegin + $untilend) / 4);
                   }
               }
           }
          
           return $quarters;
       }
mandi tek shqiperia.com
15-Sep-2006 10:15
If you have a date in the english format"Thu Sep 07 23:59:35 CEST 2006" (some times generated from logs or other systems) and you need to translate it in mm/dd/yyyy you can use the following function!
//$data="Thu Sep 07 23:59:35 CEST 2006";

function formadatedb($data)
{
   $dt=explode(" ", $data);
   $year=array ("Jan"=>1, "Feb"=>2, "Mar"=>3, "Apr"=>4, "May"=>5, "Jun"=>6, "Jul"=>7, "Aug"=>8, "Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
   return $year[$dt[1]]."/".$dt[2]."/".$dt[5];
}
russ at isitaboat dot co dot uk
06-Sep-2006 10:18
Easy way of switching between mysql and "normal" dates (english, not american)...

<?php
function flipdate($dt, $seperator_in = '-', $seperator_out = '-')
{
return
implode($seperator_out, array_reverse(explode($seperator_in, $dt)));
}
?>
michiel at mb-it dot nl
04-Sep-2006 08:59
***EDITOR NOTE: Referred to note has been removed.

The calculation function of the number of days between 2 dates by zzzdobr at gmai dot com could be done much easier:

<?
function getdays($day1,$day2)
{
  return
round((strtotime($day2)-strtotime($day1))/(24*60*60),0);
}

$begin = date("Y/m/d"); // we set today as an example
$end = "2006/11/27";
getdays($begin,$end);
?>

So now all of you know how many days you have left to buy me a birthday present ;)
James
29-Aug-2006 08:45
Slightly modified the code provided by "martin at smttuk dot com" so that you can give the function a date and/or time that you choose;

<?php
  
function zonedate($layout, $countryzone, $daylightsaving, $time)
   {
       if(
$daylightsaving) {
          
$daylight_saving = date('I');
           if(
$daylight_saving){ $zone=3600*($countryzone+1); }
       }
       else {
           if(
$countryzone>>0){ $zone=3600*$countryzone; }
           else {
$zone=0; }
       }
       if(!
$time) { $time = time(); }
      
$date = gmdate($layout, $time + $zone);
       return
$date;
   }
?>

For example if I wanted the time and date of my birthday in New Zealand time;

<?php
  
echo zonedate('Y-m-d H:i:s',-12,true,mktime(18,46,0,9,7,1986));
?>
Corey
28-Aug-2006 08:55
It's pretty simple, but in case anybody else is having problems getting the exact time they need because of DST (ex: on a Windows box in an area without DST), you can fix it all in a single line. Example...

<?php
  
echo "The time is " . date((date("I") ? intval(date("g")) - 1 : date("g")) . ":i m/d/y") . ".";
?>
martin at smttuk dot com
25-Aug-2006 07:30
/* Country Zone : Time Zone Name
-12 : Dateline Standard
-11 : Samoa Standard Time
-10 : Hawaiian Standard Time
-8 : Pacific Standard Time
-7 : Mexican Standard Time, Mountain Standard Time
-6 : Central Standard Time, Mexico Standard Time
-5 : Eastern Standard Time Eastern Time, SA Pacific Standard Time
-4 : Atlantic Standard Time, SA Western Standard Time, Pacific SA Standard Time
-3.5 : Newfoundland Standard Time
-3 : SA Eastern Standard Time, E. South America Standard Time
-2 : Mid:Atlantic Standard Time
-1 : Azores Standard Time, Cape Verde Standard Time
0 : Universal Coordinated Time, Greenwich Mean Time
1 : Romance Standard Time, Central Africa Standard Time, Central European Standard Time
2 : Egypt Standard Time, South Africa Standard Time, E. Europe Standard Time, FLE Standard Time, GTB Standard Time
3 : Arab Standard Time, E. Africa Standard Time, Arabic Standard Time, Russian Standard Time
3.5 : Iran Standard Time
4 : Arabian Standard Time, Caucasus Standard Time, Afghanistan Standard Time
5 : West Asia Standard Time
5.5 : India Standard Time
5.75 : Nepal Standard Time
6 : Central Asia Standard Time
6.5 : Myanmar Standard Time
7 : SE Asia Standard Time, North Asia Standard Time
8 : China Standard Time, W. Australia Standard Time, Singapore Standard Time, Taipei Standard Time, North Asia East Standard Time
9 : Tokyo Standard Time, Korea Standard Time, Yakutsk Standard Time
9.5 : AUS Central Standard Time, Cen. Australia Standard Time
10 : AUS Eastern Standard Time, E. Australia Standard Time
West Pacific Standard Time, Tasmania Standard Time, Vladivostok Standard Time
11 : Central Pacific Standard Time
12 : Fiji Standard Time, New Zealand Standard Time
13 : Tonga Standard Time

* How to use

   $layout =
       Same function as date : http://uk2.php.net/manual/en/function.date.php
   $countryzone =
       Country Zone from Above Eg: 0 ,for Greenwich Mean Time
   $daylightsaving =
       Set true if the Country has daylight saving it will auto change.
       Set false if the Country dose not have daylight saving or wish to it Disabled.
       (About Daylight Saving go here : http://www.timeanddate.com/time/aboutdst.html)
   Call Function:
       zonedate($layout, $countryzone, $daylightsaving);
  
   E.g.
   If GMT = Friday 25th of August 2006 10:23:17 AM
   When Function called:
   // West Asia Standard Time (Country Uses daylight saving)
       echo zonedate("l dS \of F Y h:i:s A", 5, true);
   //Output : Friday 25th of August 2006 03:23:17 PM
*/

function zonedate($layout, $countryzone, $daylightsaving)
{
if ($daylightsaving){
$daylight_saving = date('I');
if ($daylight_saving){$zone=3600*($countryzone+1);}
}
else {
   if ($countryzone>>0){$zone=3600*$countryzone;}
       else {$zone=0;}
}
$date=gmdate($layout, time() + $zone);
return $date;
}
Ron
10-Aug-2006 01:34
Example 3 is really very bad programming practice.  Calling date() more than once and putting the results together, can cause you to have a date or time that is inconsistent, or just plain invalid, because the system clock could easily change between the calls.

Instead, call time() once up front to get the timestamp, then pass that into each call to date() like this:

<?php
$now
= time();
$tomorrow  = mktime(0, 0, 0, date("m", $now)  , date("d", $now)+1, date("Y", $now));
$lastmonth = mktime(0, 0, 0, date("m", $now)-1, date("d", $now),  date("Y", $now));
$nextyear  = mktime(0, 0, 0, date("m", $now),  date("d", $now),  date("Y", $now)+1);
?>

By doing this, we ensure that we're using the same system clock sampling for all date/time field formatting, thereby ensuring the results are consistent.
mwwaygoo AT hotmail DOT com
09-Aug-2006 11:11
Number of weeks per month

I was trying to do a monthly calendar and required the number of weeks in a month, running from Monday to Sunday. Since PHP doesn't have this in its date() parameters I had to calculate it in a roundabout manner. By subtracting the week numbers away from each other we SHOULD get the number of weeks, since it is calculated on Mondays.

<?php
$year
= date("Y", $date);
$month = date("m", $date);
if( (isset(
$_GET['year'])) && (intval($_GET['year']) > 1582) )
{
  
$year = intval($_GET['year']);
}
if( (isset(
$_GET['month'])) && (intval($_GET['month']) >= 1) && (intval($_GET['month']) <= 12) )
{
  
$month = intval($_GET['month']);
}
$date = mktime(1, 1, 1, $month, date("d"), $year);

$first_day_of_month = strtotime("-" . (date("d", $date)-1) . " days", $date);
$last_day_of_month = strtotime("+" . (date("t", $first_day_of_month)-1) . " days", $first_day_of_month);

$first_week_no = date("W", $first_day_of_month);
$last_week_no = date("W", $last_day_of_month);

if(
$last_week_no < $first_week_no) $last_week_no=date("W", strtotime("-1 week",$last_week_no)) + 1;
$weeks_of_month = $last_week_no - $first_week_no + 1;

?>

The check for weeknumber of the end of the month being smaller than the beginning of the month, is because of December. Where Monday 31st is actually in the first week of the following year.
The +1 adjustment is for the number of weeks, inclusive. ie if January had five week, then 5-1=4, so we need to add an extra one to make it 5.
Phil Sylvia
09-Aug-2006 12:05
I simplified this after I figured it out based upon Mel Boyce's simple solution. Thanks Mel!

 I wanted to calculate dates based upon any given date and not just todays date which is what the hundreds of examples on the Internet use.  I created a simple function and then just call the function with 2 parameters.. the date (string) to test and the number of days that I want to add (positive #) or subtract (negative #) My intended use is to retrieve dates from the database and perform the date calculations.  This makes it simple.  I hope this helps someone as frustrated as I was. Enjoy.

******************************************
<?php

// date calculation function
// adds or subtracts a date based upon the input.
// $this_date is a string format of a valid date ie.. "2006/08/11"
// $num_days is the number of days that you would like to add (positive number) or subtract (negative number)

function fnc_date_calc($this_date,$num_days){
  
  
$my_time = strtotime ($this_date); //converts date string to UNIX timestamp
  
$timestamp = $my_time + ($num_days * 86400); //calculates # of days passed ($num_days) * # seconds in a day (86400)
    
$return_date = date("Y/m/d",$timestamp);  //puts the UNIX timestamp back into string format
  
  
return $return_date;//exit function and return string
}//end of function

$date_to_test = "2006/08/11";
$days_to_add = 7;

$past_date = fnc_date_calc($date_to_test,(($days_to_add)*-1));
$future_date = fnc_date_calc($date_to_test,$days_to_add);

echo
"Test Date is:  ".$date_to_test;
echo
"<br>";
echo
"Number of days to Calculate is: ".$days_to_add;
echo
"<br>";
echo
"Past date is:  ".$past_date;
echo
"<br>";
echo
"Future date is: ".$future_date;
?>
Matt_B at TinyOnline dot co dot uk
04-Aug-2006 11:00
In response to the getLastWeekDay() function:
***^ EDITOR NOTE: Referred to note was removed 2006-09-07.

Changing dates for any reason by adding/subtracting secret is a really bad idea. Daylight savings will totally screw up the calculations. Your best bets are the awesome strtotime features. To get last monday for example:

$var = strtotime('last monday');

Strtotime can do all sorts of funky stuff like this.
sea at zzti dot edu dot cn
03-Aug-2006 05:03
in PHP and MySQL,the day of year is different:
<?php
echo date('z',strtotime('2006-01-01'));  // print: 0
?>
mysql > SELECT DAYOFYEAR('2006-01-01');  // print: 1
28-Jul-2006 05:03
For PHP 4 users wanting a format similar to ISO 8601 (http://www.w3.org/TR/NOTE-datetime):

   echo date('Y-m-d H:i:s.0T');

returns something like 2006-07-27 16:54:14.0EDT
rev at NOSPAMO dot returntothepit dot com
28-Jul-2006 02:48
the CORRECT MySQl datetime format is
<?php
$date
= "Last Saturday";
date("Y-m-d H:i:s",strtotime($date));

$sql = "INSERT INTO pictureusageindex (`subject`,`date`) VALUES ('$subject','$date')";

echo
"$sql<br>";
?>

a person who posted above is wrong. leaving out the "-"
Bartlomiej B dot (berdzii at o2 dot pl)
25-Jul-2006 08:41
To calculate current quarter of the year we can use this simple function:

function quarter()
{
  return ceil(date("m")/3);
}
Alvin Delagon
20-Jul-2006 05:48
Here's a function that takes the year as input and returns an array or dates that are mondays. (It can be used for generating weekly reports just like I did)

function getMondays($year) {
  $newyear = $year;
  $week = 0;
  $day = 0;
  $mo = 1;
  $mondays = array();
  $i = 1;
  while ($week != 1) {
   $day++;
   $week = date("w", mktime(0, 0, 0, $mo,$day, $year));
  }
  array_push($mondays,date("r", mktime(0, 0, 0, $mo,$day, $year)));
  while ($newyear == $year) {
   $test =  strtotime(date("r", mktime(0, 0, 0, $mo,$day, $year)) . "+" . $i . " week");
   $i++;
   if ($year == date("Y",$test)) {
     array_push($mondays,date("r", $test));
   }
   $newyear = date("Y",$test);
  }
  return $mondays;
}
dulare at gmail dot com
13-Jul-2006 11:36
If You are looking for some simple date calculations:

<?

function days_between($fyear, $fmonth, $fday, $tyear, $tmonth, $tday)
{
  return
abs((mktime ( 0, 0, 0, $fmonth, $fday, $fyear) - mktime ( 0, 0, 0, $tmonth, $tday, $tyear))/(60*60*24));
}

function
day_before($fyear, $fmonth, $fday)
{
  return
date ("Y-m-d", mktime (0,0,0,$fmonth,$fday-1,$fyear));
}

function
next_day($fyear, $fmonth, $fday)
{
  return
date ("Y-m-d", mktime (0,0,0,$fmonth,$fday+1,$fyear));
}

function
weekday($fyear, $fmonth, $fday) //0 is monday
{
  return (((
mktime ( 0, 0, 0, $fmonth, $fday, $fyear) - mktime ( 0, 0, 0, 7, 17, 2006))/(60*60*24))+700000) % 7;
}

function
prior_monday($fyear, $fmonth, $fday)
{
  return
date ("Y-m-d", mktime (0,0,0,$fmonth,$fday-weekday($fyear, $fmonth, $fday),$fyear)); 
}

?>
Elena S.
06-May-2006 05:36
If you do not PHP5 yet but want a week day to be in ISO format: 1 (for Monday) through 7 (for Sunday), you can use this:
<?

//GET WEEK DAY 0 FOR SUNDAY, 6 FOR SATURDAY
$x = date( "w" );

$corrected_week_day = 7 - ( (7-$x) % (7+$x) );

?>
mel dot boyce at gmail dot com
06-Apr-2006 07:46
I've been flicking through the comments looking for some succinct date code and have noticed an alarming number of questions and over-burdened examples related to date mathematics. One of the most useful skills you can utilize when performing date math is taking full advantage of the UNIX timestamp. The UNIX timestamp was built for this kind of work.

An example of this relates to a comment made by james at bandit-dot-co-dot-en-zed. James was looking for a way to calculate the number of days which have passed since a certain date. Rather than using mktime() and a loop, James can subtract the current timestamp from the timestamp of the date in question and divide that by the number of seconds in a day:
<?php
$days
= floor((time() - strtotime("01-Jan-2006"))/86400);
print(
"$days days have passed.\n");
?>

Another usage could find itself in a class submitted by Kyle M Hall which aids in the creation of timestamps from the recent past for use with MySQL. Rather than the looping and fine tuning of a date, Kyle can use the raw UNIX timestamps (this is untested code):
<?php
$ago
= 14; // days
$timestamp = time() - ($ago * 86400);
?>

Hopefully these two examples of "UNIX-style" timestamp usage will help those finding date mathematics more elusive than it should be.
SpikeDaCruz
10-Mar-2006 03:12
The following function will return the date (on the Gregorian calendar) for Orthodox Easter (Pascha).  Note that incorrect results will be returned for years less than 1601 or greater than 2399. This is because the Julian calendar (from which the Easter date is calculated) deviates from the Gregorian by one day for each century-year that is NOT a leap-year, i.e. the century is divisible by 4 but not by 10.  (In the old Julian reckoning, EVERY 4th year was a leap-year.)

This algorithm was first proposed by the mathematician/physicist Gauss.  Its complexity derives from the fact that the calculation is based on a combination of solar and lunar calendars.

<?
function getOrthodoxEaster($date){
 
/*
   Takes any Gregorian date and returns the Gregorian
   date of Orthodox Easter for that year.
  */
 
$year = date("Y", $date);
 
$r1 = $year % 19;
 
$r2 = $year % 4;
 
$r3 = $year % 7;
 
$ra = 19 * $r1 + 16;
 
$r4 = $ra % 30;
 
$rb = 2 * $r2 + 4 * $r3 + 6 * $r4;
 
$r5 = $rb % 7;
 
$rc = $r4 + $r5;
 
//Orthodox Easter for this year will fall $rc days after April 3
 
return strtotime("3 April $year + $rc days");
}
?>
erwinmoller at xs4all dot nl
05-Jan-2006 08:34
If you need dates that are prior to 1970 (or 1901 for php5.1), have a look at calendar at this very site:
http://www.php.net/calendar
martin dot m at hid dot gr
20-Dec-2005 12:25
"It worked ok, except I noticed it had some trouble if you were spanning months, (i.e. 03-29-2005 to 04-10-2005)"

this is the (Daylight Saving Time ) problem. you can check if the start date and the end date are
whether or not in daylights savings time by using
date('I',$your_date) and to add or decrease with one hour.
Nick H
24-Nov-2005 10:21
Users in GMT may find some information on British Summer Time useful. Personally I was confused that date() for a timestamp of 0 was returning 1am, until I found about the all-year BST from 1968-71.

http://wwp.greenwichmeantime.com/info/bst2.htm
itsacon at itsacon dot net
16-Nov-2005 06:28
Caveat when using the 'W' and 'w' options together:

The 'W' option uses the ISO-8601 standard (week ends on sunday), whereas the 'w' option has the week _start_ on sunday (sunday == 0).
vernon at vernonkesner dot com
03-Nov-2005 01:37
The examples for getting a date in the past or future is simply not the best way to do it.  Especially if you are doing it dynamically.

I find the best way to get a date in the past or future is like this:

<?php
//get timestamp for past/future date I want
$pf_time = strtotime("-3 days");
//format the date using the timestamp generated
$pf_date = date("Y-m-d", $pf_time);
?>
martin at kurahaupo dot gen dot nz
31-Oct-2005 05:52
There is a mistaken impression that the maximum difference between UTC and localtime is +/- 12 hours. Right now it is summer here in New Zealand, and we're 13 hours ahead of UTC, and further east in the Chatham Islands it's UTC+13:45.

Consequently, the range for the "Z" conversion is at least -43200 ... +49500
mbirth at webwriters dot de
25-Oct-2005 06:24
Using 'B' for the Swatch Internet Time (i.Beats) can still lead to misunderstandings, because the date given in the resulting string is the local date, not the date of the BMT (Biel Mean Time / UTC+0100) after which the i.Beats are counted. So while @000 is equal all around the globe, October 25th 2005 @000 in Chicago is really October 24th, 06:00 PM local time.

Otherwise, if you use date('d M Y @B') in Chicago on that day at 6pm, it will return "24 Oct 2005 @000" although it should be "25 Oct 2005 @000".

So it may happen that you miss an appointment by 24 hours (or 1000 Beats ;-)

Here's a way to return the Internet Time with correct date:

<?php
  $curtime
= time();
 
$utcdiff = date('Z', $curtime);  // get difference to UTC in seconds
 
$bmttime = $curtime - $utcdiff + 3600// BMT = UTC+0100
 
$ssm = date('H', $bmttime)*3600 + date('i', $bmttime)*60 + date('s', $bmttime);  // seconds since midnight (BMT)
 
$ibeats = $ssm/86.4// 86400 seconds = 1000 beats, so 1 beat = 86.4 seconds

 
echo 'i.Beats    : ' . date('D, d M Y', $bmttime) . ' @' . $ibeats;
?>

Note: If you would try date('D, d M Y @B', $bmttime), the resulting beats would be wrong because the timezone used for calculation of the beats within the date() function is still your local one but the timestamp is UTC+0100. Another working way would be:

<?php
  $curtime
= time();
 
$utcdiff = date('Z', $curtime);  // get difference to UTC in seconds
 
$bmttime = $curtime - $utcdiff + 3600// BMT = UTC+0100

 
echo 'i.Beats    : ' . date('D, d M Y', $bmttime) . ' @' . date('B', $curtime);
?>

But this way there are no floating-point beats possible, which may be handy sometimes.
mendoza at pvv dot ntnu dot no
14-Oct-2005 01:38
At "daykay at pdsoftware dot de":

09 != 9 so there's nothing wrong about European vs. American formats.

$ php -r 'print 09; print "\n"; print 9; print "\n";'
0
9

09 is treated as octal and since octal numbers only use the 0-7 digits, it evaluates to 0. All numbers prefixed with 0 are considered octal just as 0x are considered hexadecimal.

http://en.wikipedia.org/wiki/Computer_numbering_formats
kbrill at multi dot com
15-Sep-2005 11:27
I created a routine that fills an array with the dates in the current week.  For example $WeekDays[0] is sunday's date, $WeekDays[1] is monday's date and so on no matter what day of the week it is today.

<?php
       $lowEnd
=date("w");
      
$lowEnd=-$lowEnd;
      
$highEnd=$lowEnd + 6;
      
$weekday=0;
       for (
$i=$lowEnd; $i<=$highEnd; $i++) {
          
$WeekDate[$weekday]=date("m/d",mktime(0, 0, 0, date("m")  , date("d")+$i, date("Y")));
          
$weekday++;
       }
?>
webmaster [AT] gn-solutions [DOT] de
07-Sep-2005 07:19
For users who want a different language than english, you can user strftime() function in combination with setlocale() instead of date():

e.g. for german language:

With date you would write:
<?php
echo date('l, d. F Y'); //Output: Wednesday, 07. September 2005
?>

With strftime() you can output it in german like this:
<?php
// Set the gloabal LC_TIME constant to german
setlocale(LC_TIME, 'de_DE');
// Little bit other Syntax but better effect
echo strftime('%A, %d. %B %Y'); //Output: Mittwoch, 07. September 2005
?>

Greetings, Andy!
steve at somejunkwelike dot com
17-Aug-2005 02:01
re: Paul_liversidge...

This is a way to get the next 10 business days, by comparing the day of the week to not be saturday or sunday.  change the top two variables to get various different results...  if you want to get the next 10 business days, starting in two days from today, change the first variable to 2, and the second to 14.  This should yield the next 10 working days.

<?php

$how_many_business_days_ahead
= 0;
$how_many_business_days_to_count = 7;

for (
$i=0;$i<$how_many_business_days_to_count;$i++)
   {
  
$jump=$i+$how_many_business_days_ahead;
  
$evalday = mktime(strftime ("%d/%m/%Y", strtotime("+$jump days")));
  
$theday = strftime("%A", strtotime("+$jump days"));   
   if(
$theday != "Saturday" and $theday != "Sunday")
       {
      
$days = $how_many_business_days_ahead+$i;
      
$the_days[$j] = strftime("%A, %B %d, %Y", strtotime("+$jump days"));
      
$j++;
       }
   }
  
  
$k = $how_many_business_days_ahead;
  
   foreach(
$the_days as $eachday)
       {
       echo
"$k business days from now = $eachday<br />";
      
$k++;
       }
  
  
?>

results:

0 business days from now = Tuesday, August 16, 2005
1 business days from now = Wednesday, August 17, 2005
2 business days from now = Thursday, August 18, 2005
3 business days from now = Friday, August 19, 2005
4 business days from now = Monday, August 22, 2005
Rob Muhlestein
06-Aug-2005 01:48
All functions that have anything to do with the internal 32-bit constrained time() system call will have this same limitation. Hopefully we'll be 64 bit by long before then, although this already creating problems with UNIX internals.
ove at junne dot dk
03-Aug-2005 02:39
I seems to me that we're rapidly apporaching another Y2K event. The date-function only handles dates up to 2038, and this is only some 30 years away. Even today is it impossible to use date() to represent my children's 50 years birthday.

Just think about it, when you're designing your code.

[ed.: This limitation is gone in PHP 5.1 and higher, although PHP itself limits integers still to 32bit]
stuff at rushsoft dot de
30-Jun-2005 05:13
ISO 8601:2000 defines:
[...] day of the year is represented by three decimal digits. The first day of any year is represented by [001] and
subsequent days are numbered in ascending sequence [...]

So don't forget increasing the return value of date("z") by one to be ISO conform, if you use this, for instance, on presentation level.
witcho at gmail dot com
08-Jun-2005 12:22
When using 'z' it should be used as how many days have passed since the beginning of the year; not as the day of the year.
"January 1" is the day 1 of the year not the day 0.
Better to add 1 when using 'z' if you really want to know the day of the year.
MG_Peter at o2 dot pl
30-Apr-2005 08:05
easy way - to convert a "datetime" form mySQL into php date format....
first - get the array form mySQL, then use

<?php
date
("d M Y H:i:s", strtotime($your_row['lastlogin_date']))
?>

strtotime - easy converts a datetime timestamp into time  ( time() or date("U")).
llewellyntd at gmail dot com
29-Apr-2005 08:50
Here is a very easy way to get the difference, in days, between two dates:

$days = (strtotime("2005-12-31") - strtotime(date("Y-m-d"))) / (60 * 60 * 24);
print $days;
jon AT standardise DOT us
16-Feb-2005 12:57
Don't forget that months start on the 1st day, and not a zero date.  Might seem obvious but:

$test = date("F Y", mktime(0, 0, 0, 12, 0, 2005));

Will return November 2005, not December.

$test = date("F Y", mktime(0, 0, 0, 12, 1, 2005));

The 1st is needed to get the right month.
ag nodot nospam at netside dot de
28-Jan-2005 11:19
Calculus of weeks in a year.

Since there is date("W") many still seem to have a problem regarding how many weeks there are in an year. Some rather complex solutions have been shown here.

It's defined, that a week which begins in december and ends in january the following year belongs to the year where most of its days lie. Therefore a week with at least 4 days in december is the last week of that year and a week with at least 4 days in january is the first week in the new year.

This concludes, that the last week of a year always contains the 28th day of december. So if you take date("W") on that day of a given year you always get the correct number of weeks for that year.
The other end of that definition is that the 4th day of january always lies in the first week of a year.

I hope this solves a lot of confusion.

(For those asking what all this fuzz about counting weeks is about: normally theres 52 weeks in a year but sometimes its 53 weeks in a year)

I wrote it down as a function, but as this is rather trivial one might consider using the date(...) only.

function weeks($year) {
   return date("W",mktime(0,0,0,12,28,$year));
}
php at document-root dot de
15-Apr-2004 01:02
To convert an unix timestamp to suite the syntax of a GeneralizedTime attribute for OpenLDAP, you can use
date ('YmdHiZO'). Note that this conversion uses local time, the recommended way is to store dates in UTC.

If your date is in UTC, just use
date ('YmdHiZ').'Z' to convert it ("Z" stands for "Zulu", which is UTC).
daniel
18-Feb-2004 06:43
The following function will return the date (on the Gregorian calendar) for Orthodox Easter (Pascha).  Note that incorrect results will be returned for years less than 1601 or greater than 2399. This is because the Julian calendar (from which the Easter date is calculated) deviates from the Gregorian by one day for each century-year that is NOT a leap-year, i.e. the century is divisible by 4 but not by 10.  (In the old Julian reckoning, EVERY 4th year was a leap-year.)

This algorithm was first proposed by the mathematician/physicist Gauss.  Its complexity derives from the fact that the calculation is based on a combination of solar and lunar calendars.

<?
function getOrthodoxEaster($date){
 
/*
   Takes any Gregorian date and returns the Gregorian
   date of Orthodox Easter for that year.
  */
 
$year = date("Y", $date);
 
$r1 = $year % 19;
 
$r2 = $year % 4;
 
$r3 = $year % 7;
 
$ra = 19 * $r1 + 16;
 
$r4 = $ra % 30;
 
$rb = 2 * $r2 + 4 * $r3 + 6 * $r4;
 
$r5 = $rb % 7;
 
$rc = $r4 + $r5;
 
//Orthodox Easter for this year will fall $rc days after April 3
 
return strtotime("3 April $year + $rc days");
}
?>