Handling Dates and Times in PHP

Date and time handling is a core part of nearly every application, from content ordering to time-based triggers. It’s also an area where subtle mistakes can easily creep in. This guide covers the most common PHP date and time operations you’ll reach for in daily work—getting and formatting the current time, constructing specific dates, working with timezones, localization, and date arithmetic.

<?php
$currentDateTime = new DateTime();
?>

Current Date and Time

The simplest way to capture the current moment is to instantiate a DateTime object:

<?php
$currentDateTime = new DateTime();
echo $currentDateTime->format('Y-m-d H:i:s'); // e.g. 2021-11-11 05:00:00
?>

PHP represents dates and times in three forms: a Unix timestamp, a DateTime object, or a formatted string. You can retrieve the current Unix timestamp alone with time(), or convert a DateTime object to one with getTimestamp():

<?php
$currentDateTime->getTimestamp();
time();
?>

Use the format() method with PHP’s date format characters to produce any string representation. Common ones include:

  • Y — four-digit year
  • m — numeric month (01–12)
  • d — day of the month (01–31)
  • H — hour in 24-hour format (00–23)
  • i — minutes (00–59)
  • s — seconds (00–59)

Constructing Specific Dates

To create a DateTime for a known date, pass a string to the constructor:

<?php
$dateTime = new DateTime('2011-07-14');
?>

The constructor also accepts relative formats and other common notations, such as 'July 14, 2011'. However, ambiguous formats can lead to unexpected results. For example, parsing '07/12/2011' via PostgreSQL will interpret it as December 7th, not July 12th, because the database format is month/day/year, while many contexts assume the reverse. If you’re not certain of the format, avoid ambiguity by specifying it explicitly:

<?php
$dateTime = DateTime::createFromFormat('Y-m-d', '2011-07-12');
?>

To build a DateTime from a Unix timestamp, use setTimestamp(). You can also format a timestamp directly without an intermediate object:

<?php
$formattedDate = date('Y-m-d', $timestamp);
?>

Timezones and DST

When constructing a DateTime, you can attach timezone information with a second constructor argument or by calling setTimezone(). PHP stores three distinct timezone_types depending on how the value was created—from an abbreviation, an offset, or a timezone identifier. Here’s how you’d convert time from New York to Jakarta:

<?php
$nyTime = new DateTime('2021-11-11 05:00:00', new DateTimeZone('America/New_York'));
echo $nyTime->setTimezone(new DateTimeZone('Asia/Jakarta'))->format('Y-m-d H:i:s');
// 2021-11-11 17:00:00
?>

PHP automatically accounts for Daylight Saving Time when you use named timezones. The same conversion one month earlier yields an 11-hour offset instead of 12, reflecting the DST shift. This makes timezone-aware arithmetic much less error-prone.

Localized Formatting

The same date is displayed very differently around the world. A U.S. audience expects a format like “November 11, 2021, 5:00 AM,” while a French user would prefer the 24-hour clock and day-before-month ordering, e.g., “11 novembre 2021 17:00.” Hand-coding each locale is impractical.

To localize properly, PHP uses the IntlDateFormatter class from the internationalization extension. On Ubuntu, you can enable it with:

<?php
sudo apt-get install php-intl
?>

Then you can produce a localized string:

<?php
$formatter = new IntlDateFormatter(
    'fr_FR',
    IntlDateFormatter::FULL,
    IntlDateFormatter::FULL,
    'America/New_York'
);
echo $formatter->format($nyTime);
?>

The first parameter is the locale, the second and third define the temporal precision for date and time (using constants like IntlDateFormatter::FULL, IntlDateFormatter::SHORT, or IntlDateFormatter::NONE to omit a component). The fourth parameter is the target timezone. Passing IntlDateFormatter::NONE for the time omits it entirely.

Date Arithmetic and Intervals

To add or subtract time, you first define a DateInterval. Its string syntax uses a P for date periods and T for time portions—for example, P1D means one day in the date portion, while PT1H is one hour in the time portion. Combine them as needed for composite durations.

<?php
$futureDate = (new DateTime())->add(new DateInterval('P1D'));
$pastDate = (new DateTime())->sub(new DateInterval('P1D'));
?>

For weekday-relative calculations, the strtotime() function accepts a broader range of natural language parameters. You can pair it with setTimestamp() on a DateTime object to move to, say, “next Monday.”

Recurring Intervals and Elapsed Time

For repeating events—like a reminder that fires every two days—DatePeriod can model the recurring range directly:

<?php
$period = new DatePeriod(
    new DateTime('2021-11-01'),
    new DateInterval('P2D'),
    new DateTime('2021-11-15')
);
foreach ($period as $date) {
    // each step is a DateTime
}
?>

To display “X hours ago” style messages, compute the difference between a past DateTime and the current time using diff(). The resulting DateInterval exposes properties such as y, m, d, and invert (which signals whether the interval is in the past). Always check invert before relying on those values.

The PHP manual’s Date and Time documentation remains the definitive reference for the full range of functions and classes discussed here, including calendar helpers not covered in this cheatsheet.