DEV Community

Cover image for Avoid this when using Date/Time functions in PHP
Marcos Rezende
Marcos Rezende

Posted on

Avoid this when using Date/Time functions in PHP

Is there any difference between getting the current date/time in the following ways in PHP?

(new \DateTimeImmutable())->format('Y-m-d H:i:s');
Enter fullscreen mode Exit fullscreen mode
\DateTimeImmutable::createFromFormat('U', (string) time())
    ->format('Y-m-d H:i:s');
Enter fullscreen mode Exit fullscreen mode

Imagine that you are inserting data into a database table using the first way, but when querying the same database table you use the second option.

While the first option will return the current date/time of your server taking into account its Time Zone configuration, the second way will return the current date/time of your server based on UTC time zone.

After creating just a single user into a users table with this data

$user->name = 'Sebastian';
$user->createdAt = (new \DateTimeImmutable())
    ->format('Y-m-d H:i:s');
Enter fullscreen mode Exit fullscreen mode

and querying the user table in this way

$dql = <<<EOT
        SELECT u FROM App\Entity\User u
        WHERE u.createdAt <= :createdAt
    EOT;

$now = \DateTimeImmutable::createFromFormat('U', (string) time())
    ->format('Y-m-d H:i:s');

$users = $this->entityManager()
    ->createQuery($dql)
    ->setParameter('createdAt', $now)
    ->getResult();
Enter fullscreen mode Exit fullscreen mode

you will receive an empty array of $users if the server which hosts your application is located in any country with Time Zone configuration greater than 0 (Austria, Denmark, Germany, and so on).

It will happen because the data which will be inserted into your user table will have the createdAt field filled with 18:14 while when you will try to query the database, you will use the time 16:14.

You didn't create any user before 16:14!

You will never find the users that you have recently created.

It occurs because when you use U to format the date/time values, you get a Unix Timestamp date/time format which gets the date/time always based on Coordinated Universal Time, and never takes into account the Server's Time Zone configuration.

This concept looks pretty basic, but maybe you have never had this issue because you have been working bellow UTC Time Zone (Denmark, South America, Canada, USA, and so on).

Pay attention to that, and you will never suffer trying to solve this issue.

Discussion (0)