Dealing with dates and times is one of those things that can frustrate programmers a lot. At the same time, they are fundamental to software development, used from everything from meta and how things are ordered to time-based triggers and lots in between.
Dates and times are prone to errors too. Handle them incorrectly, and they can confuse end-users and fellow programmers alike.
This is a quick guide to dealing with dates and times specifically in the PHP programming language. It’s meant to be a reference to the most common needs you’ll have, like formatting and adjusting dates. It’s simple, but it’s likely going to cover 80% of your needs.
Table of contents
This research is brought to you by support from Frontend Masters, CSS-Tricks’ official learning partner.
Need front-end development training?
Frontend Masters is the best place to get it. They have courses on all the most important front-end technologies. Interested in going full-stack? Here’s your best bet:
Get the current date and time
One thing to know is that the dates and times can be represented in three forms: a timestamp (i.e. epoch time), a DateTime
object, and a string.
First up, a recipe to get the current date and time:
<?php $now = new DateTime();
var_dump($now); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2021-10-13 22:25:11.790490"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
// }
This provides a DateTime
object that can be used to create a date and time string:
<?php $now = new DateTime();
echo $now->format("Y-m-d"); // 2021-10-13
echo $now->format("Y-m-d h:i:s A"); // 2021-10-13 10:10:31 PM
Intuitively, you know that Y
refers to the year, m
refers to the month, d
refers to the day of the month, and so on. The full list of the parameters can be found in the PHP manual, but I’ll drop some of the most common ones here for reference.
Day of the month | ||
d | Day of the month. two digits with leading zeros | 01 – 31 |
j | Day of the month without leading zeros | 1 – 31 |
S | Includes the English suffix. | st , nd , rd , th (e.g. 1st , 2nd , 3rd , 4th ) |
Weekday | ||
D | Abbreviated textual representation of a day, in three letters | Sun – Sat |
l | A full textual representation of a weekday. | Sunday – Saturday |
Month | ||
F | A full textual representation of a month, such as January or March | January – December |
M | Abbreviated textual representation of a month, in three letters | Jan – Dec |
m | Numeric representation of a month, with leading zeros | 01 – 12 |
n | Numeric representation of a month, without leading zeros | 1 – 12 |
Year | ||
Y | A full numeric representation of a year, 4 digits | E.g. 1999 or 2003 |
y | A two digit representation of a year | E.g. 99 or 03 |
Time | ||
A | Uppercase Ante Meridiem and Post Meridiem | AM or PM |
g | 12-hour format of an hour without leading zeros | 1 – 12 |
h | 12-hour format of an hour with leading zeros | 01 – 12 |
i | Minutes with leading zeros | 00 – 59 |
s | Seconds with leading zeros | 00 – 59 |
The DateTime
object can be converted to a timestamp:
<?php $now = new DateTime();
echo $now->getTimestamp(); // 1634139081
But we can also get the current time in timestamp without constructing a DateTime
object:
<?php echo time(); // 1634139081
Construct a DateTime
object of a specific time
What if we want to construct a DateTime
for a particular time, like July 14th, 2011? We can pass a formatted string date to the constructor:
<?php $date = new DateTime("2011-07-14");
var_dump($date); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2011-07-14 00:00:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
// }
The constructor accepts other formats as well:
<?php $date = new DateTime("14-07-2011");
var_dump($date); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2011-07-14 00:00:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
// }
But be careful with an ambiguous format, like this:
<?php $date = new DateTime("07/14/2011");
var_dump($date); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2011-07-14 00:00:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
// }
You might think that everyone should be familiar with an American date format. But not everyone is and it might be interpreted differently. Not PostgreSQL.
CREATE TABLE IF NOT EXISTS public.datetime_demo
( created_at date
); insert into datetime_demo (created_at) values ('07/12/2011'); select created_at from datetime_demo; /* 2011-12-07 */
You may have thought that would return July 12th, 2011, but it was December 7th, 2011, instead. A better way is to use an explicit format:
<?php $date = DateTime::createFromFormat('m/d/y', "10/08/21");
var_dump($date); //object(DateTime)#2 (3) {
// ["date"]=>
// string(26) "2021-10-08 16:00:47.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
//}
What if we want to construct a DateTime
object from a timestamp?
<?php $date = new DateTime();
$date->setTimestamp(1634142890);
var_dump($date); //object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2021-10-13 23:34:50.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(12) "Asia/Jakarta"
// }
We don’t have to create a DateTime
object if we want to convert a timestamp object to a formatted date string:
<?php echo date("Y-m-d h:i A", time()); // 2021-10-14 04:10 PM
Timezones
We can create a DateTime
object that includes timezone information, like if we’re dealing with Pacific Standard Time, Eastern Daylight Time, etc.
<?php $timezone = new DateTimeZone("America/New_York");
$date = new DateTime("2021-10-13 05:00", $timezone);
var_dump($date); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2021-10-13 05:00:00.000000"
// ["timezone_type"]=>
// int(3)
// ["timezone"]=>
// string(16) "America/New_York"
// } // Eastern Daylight Time, for example: New York
$date = new DateTime("2021-10-13 05:00 EDT");
var_dump($date); // object(DateTime)#2 (3) {
// ["date"]=>
// string(26) "2021-10-13 05:00:00.000000"
// ["timezone_type"]=>
// int(2)
// ["timezone"]=>
// string(3) "EDT"
// } $date = new DateTime("2021-10-13 05:00 -04:00");
var_dump($date); // object(DateTime)#1 (3) {
// ["date"]=>
// string(26) "2021-10-13 05:00:00.000000"
// ["timezone_type"]=>
// int(1)
// ["timezone"]=>
// string(6) "-04:00"
// }
There are three ways to create a DateTime
object with timezone information. The timezone_type
accepts different values for each one.
But say we want to convert a date and time that’s displayed in New York’s timezone to display Jakarta’s timezone instead?
<?php $newYorkTimeZone = new DateTimeZone("America/New_York");
$date = new DateTime("2021-11-11 05:00", $newYorkTimeZone);
echo $date->format("Y-m-d h:i A"); // 2021-11-11 05:00 AM
$jakartaTimeZone = new DateTimeZone("Asia/Jakarta");
$date->setTimeZone($jakartaTimeZone);
echo $date->format("Y-m-d h:i A"); // 2021-11-11 05:00 PM
When it’s 05:00 AM in New York, it’s 05:00 PM in Jakarta on the same day. Jakarta is 12 hours ahead of New York on November 11th 2021. But one month earlier, Jakarta is only 11 hours ahead of New York as shown below:
<?php $newYorkTimeZone = new DateTimeZone("America/New_York");
$date = new DateTime("2021-10-11 05:00", $newYorkTimeZone);
echo $date->format("Y-m-d h:i A"); // 2021-10-11 05:00 AM
$jakartaTimeZone = new DateTimeZone("Asia/Jakarta");
$date->setTimeZone($jakartaTimeZone);
echo $date->format("Y-m-d h:i A"); // 2021-10-11 04:00 PM
PHP handles Daylight Saving Time for you automatically.
Localization
This is a common way to display date and time in the United States:
<?php $now = new DateTime();
echo $now->format("m/d/Y h:i A"); // 10/14/2021 03:00 PM
But someone in France might prefer something more common to their locale. C’est horrible, they’d complain. For one, nobody puts the month before month day, except the U.S. Second, France doesn’t use AM or PM — they use the 24-hour format (e.g. 14:00 instead of 2:00 PM) like the military. This is how you make a French local happy.
<?php $now = new DateTime();
echo $now->format("d/m/Y H:i"); // 14/10/2021 15:00
But this requires an intimate knowledge about a specific country or area. Instead, we can localize the date. To localize a date in PHP, first check for support for a particular language.
In this example, we’re using the French. In Ubuntu, install the French language pack:
$ sudo apt-get install language-pack-fr
Use the strftime()
function to localize a date:
<?php setlocale(LC_TIME, "en_US.UTF-8"); // Check for U.S. English support
echo strftime("%x %X"); // 10/14/21 03:37:59 PM
setlocale(LC_TIME, "fr_FR.UTF-8"); // Check for French support
echo strftime("%x %X"); // 14/10/2021 15:37:31
All of the parameters for strftime
are documented in the PHP manual.
Time travel
Let’s do time travel to the past and the future. First, let’s get acquainted with DateInterval
:
<?php $interval = new DateInterval("P4M1W2DT2H5M"); // P 4M 1W 2D T 2H 5M
//
// P = Period interval (years, months, weeks, days)
// 4M = 4 months
// 1W = 1 week
// 2D = 2 days
//
// T = Time interval (hours, minutes, seconds)
// 2H = 2 hours
// 5M = 5 minutes
The P
and T
are to separate period interval and time interval. Here’s how we can travel to the future:
<?php $date = new DateTime("2021-10-14");
$interval = new DateInterval("P2D"); // 2 days
$futureDate = $date->add($interval);
echo $futureDate->format("Y-m-d"); // 2021-10-16
And here’s how we go back in time:
<?php $date = new DateTime("2021-10-14 10:00");
$interval = new DateInterval("PT6H"); // 6 hours
$pastDate = $date->sub($interval);
echo $pastDate->format("Y-m-d H:i"); // 2021-10-14 04:00
If we want to time travel with the name of the weekday, we can combine the strtotime()
function and the setTimestamp()
method of a DateTime
object:
<?php $nextTuesday = strtotime("next tuesday");
$date = new DateTime("2021-10-14");
$date->setTimestamp($nextTuesday);
echo $date->format("Y-m-d"); // 2021-10-19
See the full list of strtotime()
parameters in the PHP docs.
Recurring dates and times
It’s a common feature in calendar apps to set a reminder that repeats every so often, like every two days or every week. We can use DatePeriod
to represent a period of time:
<?php $start = new DateTime("2021-10-01");
$end = new DateTime("2021-11-01");
$interval = new DateInterval("P1W"); // 1 week
$range = new DatePeriod($start, $interval, $end); // Starting from October 1st 2021 (inclusive), jump every 1 week
// until November 1st 2021 (exclusive)
foreach ($range as $date) { echo $date->format("Y-m-d") . "n";
} // 2022-10-01
// 2022-10-08
// 2022-10-15
// 2022-10-22
// 2022-10-29
How many days ago?
You know how services like Twitter will show that someone posted X number of minutes/hours/days/etc. ago? We can do the same thing by calculating how much time has elapsed between the the current time and when that action occurred.
<?php $date = new DateTime("2022-10-30"); $date2 = new DateTime("2022-10-25");
$date3 = new DateTime("2022-10-10");
$date4 = new DateTime("2022-03-30");
$date5 = new DateTime("2020-03-30"); function get_period_ago($endDate, $startDate) { $dateInterval = $endDate->diff($startDate); if ($dateInterval->invert==1) { if ($dateInterval->y > 0) { return $dateInterval->y . " years agon"; } if ($dateInterval->m > 0) { return $dateInterval->m . " months agon"; } if ($dateInterval->d > 7) { return (int)($dateInterval->d / 7) . " weeks agon"; } if ($dateInterval->d > 0) { return $dateInterval->d . " days agon"; } }
} echo get_period_ago($date, $date2); // 5 days ago
echo get_period_ago($date, $date3); // 2 weeks ago
echo get_period_ago($date, $date4); // 7 months ago
echo get_period_ago($date, $date5); // 2 years ago
After getting the DateInterval
object from the diff()
method, make sure that the $startDate
variable is in the past by checking the invert
property. Then check the y
, m
, and d
properties.
The full list of DateInterval
object properties can be found here in the PHP docs.
Where do you go from here?
Now you have a little cheatsheet of common PHP recipes for when you find yourself working with dates and times. Need to get the current date and time? Maybe you need to format a date a certain way, or include the local timezone, or compare dates. All of that is right here!
There are still more methods and functions about date and time that we haven’t discussed, of course — things like calendar-related functions and whatnot. Be sure to keep the PHP Manual’s Date and Time section close by for even more use cases and examples.