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");
}
/**
* This function calculates the number of days between the first and the second date. Arguments must be subclasses of DateTime
**/
static function differenceInDays ($firstDate, $secondDate){
$firstDateTimeStamp = $firstDate->format("U");
$secondDateTimeStamp = $secondDate->format("U");
$rv = round ((($firstDateTimeStamp - $secondDateTimeStamp))/86400);
return $rv;
}
/**
* This function returns an object of DateClass from $time in format $format. See date() for possible values for $format
**/
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;
}
}
?>
The DateTime class
(PHP 5 >= 5.2.0)
Introduction
Representation of date and time.
Class synopsis
DateTime
{
/* Constants */
/* Methods */
public static DateTime createFromFormat
( string
}$format
, string $time
[, DateTimeZone $timezone
] )Predefined Constants
-
DateTime::ATOMDATE_ATOM - Atom (example: 2005-08-15T15:52:01+00:00)
- HTTP Cookies (example: Monday, 15-Aug-05 15:52:01 UTC)
-
DateTime::ISO8601DATE_ISO8601 - ISO-8601 (example: 2005-08-15T15:52:01+0000)
-
DateTime::RFC822DATE_RFC822 - RFC 822 (example: Mon, 15 Aug 05 15:52:01 +0000)
-
DateTime::RFC850DATE_RFC850 - RFC 850 (example: Monday, 15-Aug-05 15:52:01 UTC)
-
DateTime::RFC1036DATE_RFC1036 - RFC 1036 (example: Mon, 15 Aug 05 15:52:01 +0000)
-
DateTime::RFC1123DATE_RFC1123 - RFC 1123 (example: Mon, 15 Aug 2005 15:52:01 +0000)
-
DateTime::RFC2822DATE_RFC2822 - RFC 2822 (Mon, 15 Aug 2005 15:52:01 +0000)
-
DateTime::RFC3339DATE_RFC3339 -
Same as
DATE_ATOM(since PHP 5.1.3) -
DateTime::RSSDATE_RSS - RSS (Mon, 15 Aug 2005 15:52:01 +0000)
-
DateTime::W3CDATE_W3C - World Wide Web Consortium (example: 2005-08-15T15:52:01+00:00)
Changelog
| Version | Description |
|---|---|
| 5.2.2 | DateTime object comparison with the comparison operators changed to work as expected. Previously, all DateTime objects were considered equal (using ==). |
Table of Contents
- DateTime::add — Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object
- DateTime::__construct — Returns new DateTime object
- DateTime::createFromFormat — Returns new DateTime object formatted according to the specified format
- DateTime::diff — Returns the difference between two DateTime objects
- DateTime::format — Returns date formatted according to given format
- DateTime::getLastErrors — Returns the warnings and errors
- DateTime::getOffset — Returns the timezone offset
- DateTime::getTimestamp — Gets the Unix timestamp
- DateTime::getTimezone — Return time zone relative to given DateTime
- DateTime::modify — Alters the timestamp
- DateTime::__set_state — The __set_state handler
- DateTime::setDate — Sets the date
- DateTime::setISODate — Sets the ISO date
- DateTime::setTime — Sets the time
- DateTime::setTimestamp — Sets the date and time based on an Unix timestamp
- DateTime::setTimezone — Sets the time zone for the DateTime object
- DateTime::sub — Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object
- DateTime::__wakeup — The __wakeup handler
ediathome ¶
3 years ago
tim at timfennis dot com ¶
2 months ago
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
/**
On my local machine this results in:
2013-03-01T16:15:09+01:00
2013-03-01T16:15:09+0100
Both of these strings are valid ISO8601 datetime strings, but the latter is not accepted by the constructor of JavaScript's date object on iPhone. (Possibly other browsers as well)
*/
?>
Our solution was to create the following constant on our DateHelper object.
<?php
class DateHelper
{
/**
* An ISO8601 format string for PHP's date functions that's compatible with JavaScript's Date's constructor method
* Example: 2013-04-12T16:40:00-04:00
*
* PHP's ISO8601 constant doesn't add the colon to the timezone offset which is required for iPhone
**/
const ISO8601 = 'Y-m-d\TH:i:sP';
}
?>
php at keith tyler dot com ¶
10 months ago
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 ) ;
/* returns:
DateInterval Object
(
[y] => 0
[m] => 0
[d] => 0
[h] => 0
[i] => 0
[s] => 0
[invert] => 0
[days] => 0
)
*/
?>
You get back 0 when you actually want to get 0.251066 seconds.
bf at tbwb dot nl ¶
2 years ago
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"
marcio dot barbado at bdslabs dot com dot br ¶
1 year ago
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();
?>
petepostma@google ¶
2 months ago
const string RFC822 = "D, d M y H:i:s O" ;
would be incorrect; 822 != 2822.
822 defines the timezone to be a limited set of characters, preferably 'GMT', not digits like 2822.
const string RFC822 = "D, d M y H:i:s T" ;
gmblar+php at gmail dot com ¶
3 years ago
Small but powerful extension to DateTime
<?php
class Blar_DateTime extends DateTime {
/**
* Return Date in ISO8601 format
*
* @return String
*/
public function __toString() {
return $this->format('Y-m-d H:i');
}
/**
* Return difference between $this and $now
*
* @param Datetime|String $now
* @return DateInterval
*/
public function diff($now = 'NOW') {
if(!($now instanceOf DateTime)) {
$now = new DateTime($now);
}
return parent::diff($now);
}
/**
* Return Age in Years
*
* @param Datetime|String $now
* @return Integer
*/
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>
?>
nodweber at gmail dot com ¶
1 year ago
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
giorgio dot liscio at email dot it ¶
2 years ago
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
tom at r dot je ¶
3 years ago
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.
Julien ¶
9 months ago
DateTime extension that work with millisecond
<?php
class MilliSecondDateTime extends Datetime{
private $millisecond;
public function __construct($time = NULL,$time_zone = NULL){
if(is_null($time))
$time = '@'.microtime(true);
if(is_null($time_zone))
$time_zone = new DateTimeZone('UTC');
if(preg_match('/@(\\\\d+)\\\\.(\\\\d+)/',$time,$matches)){
$this->millisecond = $matches[2];
parent::__construct('@'.$matches[1],$time_zone);
} else {
$this->millisecond = 0;
parent::__construct($time,$time_zone);
}
}
public function getSQLDate(){
return $this->format('Y-m-d G:i:s').'.'.$this->millisecond;
}
}
?>
Note that sub() method continue to work with millisecond
