PHP: How do you get the current date and time?
Printing the current date is one line of code. As soon as you calculate with it or display it in another time zone, though, a few things come along that are worth knowing.
The quick way
<?php
echo date('Y-m-d H:i:s'); // 2026-08-28 22:08:12
echo date('d.m.Y'); // 28.08.2026
echo date('Y'); // 2026
?>
date() formats the current time according to a pattern. If all you need is the year or the day, you are done here.
The time zone comes first
This is the most common reason for “the time is wrong”. PHP uses the time zone
configured in php.ini, and that is often UTC. The same moment then looks like
this:
12:00 in UTC : 2026-08-28 12:00:00 UTC
derselbe Zeitpunkt : 2026-08-28 14:00:00 CEST
The Unix timestamp is identical in both cases, only the display differs. You can
set the time zone globally in php.ini:
date.timezone = Europe/Vienna
or at runtime:
<?php
date_default_timezone_set('Europe/Vienna');
?>
If you store moments in a database, store them in UTC and convert only when displaying. Then you have no trouble with daylight saving time and none with users in other time zones.
The better way: DateTimeImmutable
As soon as you do more than display, use an object:
<?php
$now = new DateTimeImmutable('now', new DateTimeZone('Europe/Vienna'));
echo $now->format('d.m.Y'); // 28.08.2026
echo $now->format(DATE_ATOM); // 2026-08-28T22:08:12+02:00
echo $now->getTimestamp(); // 1787947692
?>
DATE_ATOM is handy when the value leaves through an interface — the format is
unambiguous and includes the time zone.
Why immutable?
There are two classes: DateTime and DateTimeImmutable. The difference is
bigger than the name suggests:
<?php
$a = new DateTimeImmutable('2026-08-28 10:00:00');
$b = $a->modify('+1 day');
$c = new DateTime('2026-08-28 10:00:00');
$d = $c->modify('+1 day');
?>
DateTimeImmutable $a : 2026-08-28 (unchanged)
$b : 2026-08-29
DateTime $c : 2026-08-29 <- changed!
$d : 2026-08-29
With DateTime, modify() changes the object itself and returns it as
well. Afterwards $c and $d are two names for the same object. Pass such an
object to a function that calculates with it and you end up with a different
date than before, without that being visible at the call site.
When in doubt, always use DateTimeImmutable.
Calculating with time
<?php
$start = new DateTimeImmutable('2026-08-28 23:30:00');
$end = $start->add(new DateInterval('PT2H')); // +2 hours
echo $end->format('Y-m-d H:i'); // 2026-08-29 01:30
echo $start->modify('+1 month')->format('Y-m-d'); // 2026-09-28
?>
DateInterval takes a specification in ISO 8601 format: P introduces the
period, T separates off the time part. So PT2H is two hours, P1D one day,
P1M one month.
The month trap
And now the place where many people are surprised:
31.01. + 1 month => 2026-03-03
Not 28 February, but 3 March. The reason is how it is calculated: PHP first increments the month number and normalises afterwards. So “31 February” becomes 3 March, because February 2026 only has 28 days.
That is documented behaviour and not a bug, but it surprises people reliably. If you want what is usually meant, say so explicitly:
<?php
echo $jan31->modify('last day of next month')->format('Y-m-d'); // 2026-02-28
?>
strtotime understands text too
For quick cases strtotime() is very handy:
'now' => 2026-08-28
'tomorrow' => 2026-08-29
'next monday' => 2026-08-31
'+2 weeks' => 2026-09-11
'last day of this month' => 2026-08-31
You can pass the same expressions to DateTimeImmutable and modify().
Invalid input
Here the two routes behave differently:
new DateTimeImmutable('kein datum') : DateMalformedStringException
strtotime('kein datum') : false
Since PHP 8.3 there is a dedicated exception for this,
DateMalformedStringException. strtotime() on the other hand only returns
false — and because false counts as 0 in arithmetic, you end up at
1 January 1970 if you are not careful. So check the return value with ===.
Summary
- Set the time zone, otherwise you are calculating in UTC without noticing.
date()for display,DateTimeImmutablefor calculation.DateTimemodifies itself onmodify(),DateTimeImmutabledoes not.31 Jan + 1 monthis 3 March, not 28 February.- Store UTC in the database and convert only when displaying.
About Netcup (advertisement)
The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).