It's a common task to work with date and time as a web developer. If you are still using functions like strtotime and date to work with date and time, you are missing out.
PHP provides a dedicated class DateTime for dealing with date and time. Most of people have been ignoring it, despite it has been available since PHP 5.2.
A couple of reasons why you should use DateTime over strtotime and date:
Instantiating an DateTime object is no different from instantiating any other objects in PHP. We instantiate an DateTime object via its constructor.
When no parameter is supplied, an DateTime object with current timestamp and the default timezone will be created. The default timezone is normally configured in php.ini file.
For example, to create a "now" DateTime object:
$currentDateTime = new DateTime();
Optionally we can supply a string, which represents a valid date and time, as the first parameter of the DateTime's constructor. The default timezone will still be used since it is not specified.
A few examples of creating DateTime objects with valid time string:
$yesterday = new DateTime('yesterday');
$twoDaysLater = new DateTime('+ 2 days');
$oneWeekEarly = new DateTime('- 1 week');
The second parameter of the DateTime's constructor allows us to specify a timezone. This parameter accepts a DateTimeZone object only.
For example, to create a DateTime object with Singapore timezone:
$yesterdayInSingapore = new DateTime('yesterday', new DateTimeZone('Singapore'));
Of cause, we can also create a DateTime object with traditional date string:
$dateTime = new DateTime('2015-01-01 12:30:12');
We will always want a specific format depends on the system we are building.
Formatting a DateTime object to get a custom string representation is straightforward. It's done via DateTime's format() method.
DateTime::format() accepts a single string parameter. This string should contain options listed at PHP official page.
For example, to get a yyyy-dd-mm format outputted by DateTime, we can do:
$now = new DateTime();
$ymdNow = $now->format('Y-m-d');
We can create any desired format, because the format parameter provides all the possible options.
A few more examples:
print_r($now->format('jS F Y'));
print_r($now->format('ga jS M Y'));
print_r($now->format('Y/m/d s:i:H'));
// Output:
6th January 2016
1am 6th Jan 2016
2016/01/06 11:39:01
When working with date string, we need to convert them to timestamp using strtotime in order to compare their value.
DateTime objects work with comparison operators out of box. We can directly compare two DateTime objects just like two numeric values.
A few examples of comparing two DateTime objects:
$today = new DateTime('today');
$yesterday = new DateTime('yesterday');
var_dump($today > $yesterday);
var_dump($today < $yesterday);
var_dump($today == $yesterday);
// Output
bool(true)
bool(false)
bool(false)
Sometimes, a Boolean value of comparing two dates objects is not sufficient. We may want to know the exact difference between two dates.
DateTime::diff is a function for getting the difference between two DateTime objects. This function returns a DateInterval object, which we can use to retrieve any desired interval format through its function DateInterval::format.
For example, to get days difference between $today and $yesterday, we can do:
$interval = $today->diff($yesterday);
echo $interval->format('%d day ago')
// Output
1 day ago
There are a number of interval properties in DateInterval class, you can check them out at PHP official site.
Though in reality, we can never manipulate time, with DateTime, we can actually do that. This means DateTime objects are mutable.
Adding to an existing DateTime is done through function DateTime::add. DateTime::add accepts a single DateInterval object parameter.
Let's demonstrate how addition works in a simple example:
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
$today->add(new DateInterval('P2D'));
echo $today->format('Y-m-d') . PHP_EOL;
// Output
2016-01-06
2016-01-08
Most of the code above is easy to understand. The only tricky part may be creating a DateInterval object. DateInterval's constructor accepts a string that contains a valid interval specification.
An intercept of explanation for interval specification from PHP official site:
The format starts with the letter P, for "period." Each duration period is represented by an integer value followed by a period designator. If the duration contains time elements, that portion of the specification is preceded by the letter T.
In our code above, we have used 'P2D', which standards for two days, to create a DateInterval object.
Similar to DateTime::add, subtraction is done through function DateTime::sub. DateTime::sub function accepts a DateInterval object just like DateTime::add function.
To subtract two days from $today, we can do:
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
$today->modify('-2 days');
echo $today->format('Y-m-d') . PHP_EOL;
// Output
2016-01-06
2016-01-04
Modification of a DateTime object is also possible with DateTime::modify function.
Comparing to DateTime::add function and DateTime::sub function, DateTime::modify function takes a different type of parameter to do the job. It accepts a date/time string. There is a wide range of support for the date/time string, you can check them out in details at PHP official site.
To subtract two days from $today with DateTime::modify function, we can do:
$today = new DateTime('today');
echo $today->format('Y-m-d') . PHP_EOL;
$today->modify('-2 days');
echo $today->format('Y-m-d') . PHP_EOL;
// Output
2016-01-06
2016-01-04
You have learned how to create, format, compare and even manipulate DateTime object so far. With what you have learned, you should be able to replace functions such as strtotime and date with DateTime object confidently in your future projects.
Sooner or later, you will be using DateTime objects for doing the same tasks over and over again. That has been the case for most of developers.
Tasks such as calculating someone's age based on his birthday or testing if a date is tomorrow are pretty common. PHP developers decided to consolidate various tasks that involving DateTime into some generic packages. Hence a number of packages related to DateTime were developed over the years.
Some outstanding ones are recommended by the community. We will encourage you to check out two of them as shown below. They are notably good. Because they not only provide a lot of help functions for dealing with DateTime, but also they are well documented.
Links to mentioned resources.
Characters recognized when using DateTime::format function:
http://php.net/manual/en/function.date.php#refsect1-function.date-parameters
Date interval specification:
http://php.net/manual/en/class.dateinterval.php#dateinterval.props
Supported date/time string in PHP:
http://php.net/manual/en/datetime.formats.php
Carbon: A simple PHP API extension for DateTime:
http://carbon.nesbot.com/
Chronos: It provides a zero-dependency collection of extensions to the DateTime object.
http://book.cakephp.org/3.0/en/chronos.html