PHP Date and Time Recipes

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:

// 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:
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 monthdDay of the month. two digits with leading zeros01 – 31jDay of the month without leading zeros1 – 31SIncludes the English suffix.st, nd, rd, th (e.g. 1st, 2nd, 3rd, 4th)WeekdayDAbbreviated textual representation of a day, in three lettersSun – SatlA full textual representation of a weekday.Sunday – SaturdayMonthFA full textual representation of a month, such as January or MarchJanuary – DecemberMAbbreviated textual representation of a month, in three lettersJan – DecmNumeric representation of a month, with leading zeros01 – 12nNumeric representation of a month, without leading zeros1 – 12YearYA full numeric representation of a year, 4 digitsE.g. 1999 or 2003yA two digit representation of a yearE.g. 99 or 03TimeAUppercase Ante Meridiem and Post MeridiemAM or PMg12-hour format of an hour without leading zeros1 – 12h12-hour format of an hour with leading zeros01 – 12iMinutes with leading zeros00 – 59sSeconds with leading zeros00 – 59The DateTime object can be converted to a timestamp:
getTimestamp(); // 1634139081
But we can also get the current time in timestamp without constructing a DateTime object:

// 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:

// 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:

// 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:

// 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?
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:

// 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?
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:
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:
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.
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:
add($interval);
echo $futureDate->format(“Y-m-d”); // 2021-10-16
And here’s how we go back in time:
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:
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:
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.
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.

Typed at

Share your love

Leave a Reply