©
This document uses PHP Chinese website manual Release
(PHP 5 >= 5.2.0, PHP 7)
Representation of date and time.
$time
= "now"
[, DateTimeZone $timezone
= NULL
]] )$interval
)$format
, string $time
[, DateTimeZone $timezone
] )$modify
)$array
)$year
, int $month
, int $day
)$year
, int $week
[, int $day
= 1
] )$hour
, int $minute
[, int $second
= 0
] )$unixtimestamp
)$timezone
)$interval
)$datetime2
[, bool $absolute
= false
] )$format
)DateTime::ATOM
DATE_ATOM
DATE_COOKIE
DateTime::ISO8601
DATE_ISO8601
Note: This format is not compatible with ISO-8601, but is left this way for backward compatibility reasons. Use
DateTime::ATOM
orDATE_ATOM
for compatibility with ISO-8601 instead.
DateTime::RFC822
DATE_RFC822
DateTime::RFC850
DATE_RFC850
DateTime::RFC1036
DATE_RFC1036
DateTime::RFC1123
DATE_RFC1123
DateTime::RFC2822
DATE_RFC2822
DateTime::RFC3339
DATE_RFC3339
DATE_ATOM
(since PHP 5.1.3)
DateTime::RSS
DATE_RSS
DateTime::W3C
DATE_W3C
版本 | 说明 |
---|---|
5.5.0 | The class now implements DateTimeInterface. |
5.4.24 | The COOKIE constant was changed to reflect RFC 1036 using a four digit year rather than a two digit year (RFC 850) as prior versions. |
5.2.2 | DateTime object comparison with the comparison operators changed to work as expected. Previously, all DateTime objects were considered equal (using ==). |
[#1] anthony at teamug dot net [2015-09-13 14:00:03]
This is a great class, but unless you need to use it's more advanced features, I would stick to passing times around your scripts as Unix Time Stamps - maybe prefixing with "uts".
Otherwise you will simply be creating more lines of code with no benefit.
[#2] ryan at amst dot com [2015-08-21 20:09:52]
It seems like, due to changes in the DateTimeZone class in PHP 5.5, when creating a date and specifying the timezone as a a string like 'EDT', then getting the timezone from the date object and trying to use that to set the timezone on a date object you will have problems but never know it. Take the following code:
<?php
$date = new DateTime('2015-08-21 15:00:00 EDT') ;
$tz_string = $date->getTimezone()->getName() ;
$tz = new DateTimeZone($tz_string) ;
$date->setTimezone($tz) ;
?>
You would think this code should not change $date at all, but it does. It seems like you can create a timezone object like 'EDT' but can't use those to set timezones properly. The process, however does act like it's working without errors.
[#3] tdp [2015-01-20 23:17:05]
Be aware of this behaviour:
<?php
$dt1 = new \DateTime( '2014/12/31' );
$dt1->modify( '-1 month' );
$m = (int) $dt1->format( 'm' );
var_dump( $m ); // still 12 !!!
$dt2 = new \DateTime( '2014/12/30' );
$dt2->modify( '-1 month' );
$m = (int) $dt2->format( 'm' );
var_dump( $m ); // 11
?>
The method modify( '-1 month' ) appear to remove 30 days, not to subtract 1 from the month and adjust the day (if needed).
In my opinion, the former date should be adjusted to 2014/11/30, that is, the last day in the previous month.
[#4] julie at earthshod dot co dot uk [2014-01-29 16:55:01]
It isn't obvious from the above, but you can insert a letter of the alphabet directly into the date string by escaping it with a backslash in the format string. Note that if you are using "double" speech marks around the format string, you will have to further escape each backslash with another backslash! If you are using 'single' speech marks around the format string, then you only need one backslash.
For instance, to create a string like "Y2014M01D29T1633", you *could* use string concatenation like so:
<?php
$dtstring = "Y" . date("Y", $when) . "M" . date("m", $when) . "D" . date("d", $when) . "T" . date("Hi", $when);
?>
but you could also escape the letters with backslashes like so:
<?php
$dtstring1 = date('\YY\Mm\Dd\THi', $when);
$dtstring2 = date("\\YY\\Mm\\Dd\\THi", $when);
?>
This method involves fewer function calls, so probably is slightly quicker; and also is immune to race conditions if you are not specifying the second argument. [It's possible that you could evaluate date("d") just *before* midnight and date("H") just *after* midnight. This will not give you the result you were expecting.]
[#5] stevenmattera at gmail dot com [2014-01-10 14:04:58]
This caused some confusion with a blog I was working on and just wanted to make other people aware of this. If you use createFromFormat to turn a date into a timestamp it will include the current time. For example:
<?php
$publishDate = DateTime::createFromFormat('m/d/Y', '1/10/2014');
echo $publishDate->getTimestamp();
?>
Would not output the expected "1389312000" instead it would output something more like "1389344025". To fix this you would want to do:
<?php
$publishDate = DateTime::createFromFormat('m/d/Y', '1/10/2014');
$publishDate->setTime(0, 0, 0);
echo $publishDate->getTimestamp();
?>
I hope this helps someone!
[#6] James [2013-10-09 15:44:11]
Be aware that DateTime may ignore fractional seconds for some formats, but not when using the ISO 8601 time format, as documented by this bug:
https://bugs.php.net/bug.php?id=51950
$dateTime = DateTime::createFromFormat(
DateTime::ISO8601,
'2009-04-16T12:07:23.596Z'
);
// bool(false)
[#7] tim at timfennis dot com [2013-03-01 15:20:04]
There is a subtle difference between the following two statments which causes JavaScript's Date object on iPhones to fail.
<?php
$objDateTime = new DateTime('NOW');
echo $objDateTime->format('c'); // ISO8601 formated datetime
echo $objDateTime->format(DateTime::ISO8601); // Another way to get an ISO8601 formatted string
?>
Our solution was to create the following constant on our DateHelper object.
<?php
class DateHelper
{
const ISO8601 = 'Y-m-d\TH:i:sP';
}
?>
[#8] php at keith tyler dot com [2012-06-08 17:03:26]
DateTime does not support split seconds (microseconds or milliseconds etc.)
I don't know why this isn't documented.
The class constructor will accept them without complaint, but they are discarded.
There does not appear to be a way to take a string like "2012-07-08 11:14:15.638276" and store it in an objective form in a complete way.
So you cannot do date math on two strings such as:
<?php
$d1=new DateTime("2012-07-08 11:14:15.638276");
$d2=new DateTime("2012-07-08 11:14:15.889342");
$diff=$d2->diff($d1);
print_r( $diff ) ;
?>
You get back 0 when you actually want to get 0.251066 seconds.
[#9] marcio dot barbado at bdslabs dot com dot br [2012-03-22 18:22:36]
DateTime class does not use locales so here I test and compare its formating with strftime() function's one:
<?php
// Under UNIX, command "$ locale -a" should provide you with your server's options.
$data_do_mysql = "2011-09-29 23:50:26";
echo '<strong>' . "\$data_do_mysql" . '</strong>' . ":" . $data_do_mysql . "." . '<br />' .
'<br />';
$dataInicial = new DateTime(trim($data_do_mysql));
// setlocale() used with strftime().
$meu_locale = setlocale(LC_ALL, "pt_BR.utf8");
$data_inicial = strftime("%d de %b de %Y", strtotime(trim($data_do_mysql)));
// Outputs:
// $data_do_mysql formatada com a classe DateTime:29-Sep-2011.
echo '<strong>' . "\$data_do_mysql" . '</strong>' . " formatada com a classe DateTime:" . $dataInicial->format('d-M-Y') . "." . '<br />' .
'<br />';
// Outputs:
// $data_do_mysql formatada com a fun??o strftime():29 de Set de 2011.
echo '<strong>' . "\$data_do_mysql" . '</strong>' . " formatada com a função strftime():" . $data_inicial . "." . '<br />' .
'<br />';
// setlocale() fails :-(
if (!$meu_locale)
{
echo "Prefiro usar DateTime.";
}
// Yay setlocale() :-D
else
{
echo "Prefiro usar strftime().";
}
exit();
?>
[#10] nodweber at gmail dot com [2011-07-19 02:22:40]
IF You want to create clone of $time, use clone..
<?php
$now = new DateTime;
$clone = $now; //this doesnot clone so:
$clone->modify( '-1 day' );
echo $now->format( 'd-m-Y' ), "\n", $clone->format( 'd-m-Y' );
echo '----', "\n";
// will print same.. if you want to clone make like this:
$now = new DateTime;
$clone = clone $now;
$clone->modify( '-1 day' );
echo $now->format( 'd-m-Y' ), "\n", $clone->format( 'd-m-Y' );
?>
Results:
18-07-2011
18-07-2011
----
19-07-2011
18-07-2011
[#11] giorgio dot liscio at email dot it [2010-08-13 22:24:06]
please note that using
setTimezone
setTimestamp
setDate
setTime
etc..
will modify the original object, and the return value is $this
$original = new DateTime("now");
$modified = $original->setTimezone(new DateTimezone("europe/rome"));
echo $original === $modified ? "THE OBJECT IS THE SAME" : "OBJECTS ARE DIFFERENT";
so a datetime object is mutable
(Editors note: PHP 5.5 adds DateTimeImmutable which does not modify the original object, instead creating a new instance.)
[#12] bf at tbwb dot nl [2010-08-10 03:19:18]
If you have timezone information in the time string you construct the DateTime object with, you cannot add an extra timezone in the constructor. It will ignore the timezone information in the time string:
$date = new DateTime("2010-07-05T06:00:00Z", new DateTimeZone("Europe/Amsterdam"));
will create a DateTime object set to "2010-07-05 06:00:00+0200" (+2 being the TZ offset for Europe/Amsterdam)
To get this done, you will need to set the timezone separately:
$date = new DateTime("2010-07-05T06:00:00Z");
$date->setTimeZone(new DateTimeZone("Europe/Amsterdam");
This will create a DateTime object set to "2010-07-05 08:00:00+0200"
[#13] ediathome [2010-03-20 01:21:05]
If you need DateTime::createFromFormat functionality in versions <5.3.0 releases you might use the following basic class which can also be combined with Tom's class. It should work for most basic formats, however you should improve this function if you need more complex formats.
<?php
class DateClass extends DateTime{
public function getTimestamp(){
return $this->format ("U");
}
static function differenceInDays ($firstDate, $secondDate){
$firstDateTimeStamp = $firstDate->format("U");
$secondDateTimeStamp = $secondDate->format("U");
$rv = round ((($firstDateTimeStamp - $secondDateTimeStamp))/86400);
return $rv;
}
static function createFromFormat ($format, $time){
assert ($format!="");
if($time==""){
return new DateClass();
}
$regexpArray['Y'] = "(?P<Y>19|20\d\d)";
$regexpArray['m'] = "(?P<m>0[1-9]|1[012])";
$regexpArray['d'] = "(?P<d>0[1-9]|[12][0-9]|3[01])";
$regexpArray['-'] = "[-]";
$regexpArray['.'] = "[\. /.]";
$regexpArray[':'] = "[:]";
$regexpArray['space'] = "[\s]";
$regexpArray['H'] = "(?P<H>0[0-9]|1[0-9]|2[0-3])";
$regexpArray['i'] = "(?P<i>[0-5][0-9])";
$regexpArray['s'] = "(?P<s>[0-5][0-9])";
$formatArray = str_split ($format);
$regex = "";
// create the regular expression
foreach($formatArray as $character){
if ($character==" ") $regex = $regex.$regexpArray['space'];
elseif (array_key_exists($character, $regexpArray)) $regex = $regex.$regexpArray[$character];
}
$regex = "/".$regex."/";
// get results for regualar expression
preg_match ($regex, $time, $result);
// create the init string for the new DateTime
$initString = $result['Y']."-".$result['m']."-".$result['d'];
// if no value for hours, minutes and seconds was found add 00:00:00
if (isset($result['H'])) $initString = $initString." ".$result['H'].":".$result['i'].":".$result['s'];
else {$initString = $initString." 00:00:00";}
$newDate = new DateClass ($initString);
return $newDate;
}
}
?>
[#14] gmblar+php at gmail dot com [2010-01-24 08:53:46]
Small but powerful extension to DateTime
<?php
class Blar_DateTime extends DateTime {
public function __toString() {
return $this->format('Y-m-d H:i');
}
public function diff($now = 'NOW') {
if(!($now instanceOf DateTime)) {
$now = new DateTime($now);
}
return parent::diff($now);
}
public function getAge($now = 'NOW') {
return $this->diff($now)->format('%y');
}
}
?>
Usage:
<?php
$birthday = new Blar_DateTime('1879-03-14');
// Example 1
echo $birthday;
// Result: 1879-03-14 00:00
// Example 2
echo '<p>Albert Einstein would now be ', $birthday->getAge(), ' years old.</p>';
// Result: <p>Albert Einstein would now be 130 years old.</p>
// Example 3
echo '<p>Albert Einstein would now be ', $birthday->diff()->format('%y Years, %m Months, %d Days'), ' old.</p>';
// Result: <p>Albert Einstein would now be 130 Years, 10 Months, 10 Days old.</p>
// Example 4
echo '<p>Albert Einstein was on 2010-10-10 ', $birthday->getAge('2010-10-10'), ' years old.</p>';
// Result: <p>Albert Einstein was on 2010-10-10 131 years old.</p>
?>
[#15] tom at r dot je [2009-06-10 08:00:18]
If you're stuck on a PHP 5.1 system (unfortunately one of my clients is on a rather horrible webhost who claims they cannot upgrade php) you can use this as a quick workaround:
<?php
if (!class_exists('DateTime')) {
class DateTime {
public $date;
public function __construct($date) {
$this->date = strtotime($date);
}
public function setTimeZone($timezone) {
return;
}
private function __getDate() {
return date(DATE_ATOM, $this->date);
}
public function modify($multiplier) {
$this->date = strtotime($this->__getDate() . ' ' . $multiplier);
}
public function format($format) {
return date($format, $this->date);
}
}
}
?>
it is NOT perfect. Timezones and DST are not supported, but if you just need compatible basic functions this works. Feel free to complete this so it's compatible with the 5.2 datetime object.