Home » Php » datetime – Error converting to UTC after 2038 on 64 bit unix PHP

datetime – Error converting to UTC after 2038 on 64 bit unix PHP

Posted by: admin July 12, 2020 Leave a comment

Questions:

I need to convert date time information from local time (gtm+1) to UTC using php (5.4)
on Centos 7.4 64 bits

I tried the following procedure :

function convertToUtc ($date)
{
  $dateTime = new DateTime ($date, new DateTimeZone('Europe/Rome'));
  $dateTime->setTimezone(new DateTimeZone('UTC'));
  return $dateTime->format('Y-m-d') . 'T' . $dateTime->format('H:i:s') . 'Z';
}

This works until 2038, after that it miscalculates DST returning always an offset of 1 hour:

2037 : all ok

LOCAL TIME           ->  UTC TIME

2037-03-28 10:12:13  ->  2037-03-28T09:12:13Z   the day before dst change

2037-03-29 10:12:13  ->  2037-03-29T08:12:13Z   the first DST day

2037-10-24 10:12:13  ->  2037-10-24T08:12:13Z   the last DST day

2037-10-25 10:12:13  ->  2037-10-25T09:12:13Z   the day after


2038 : ok until dst change

2038-03-27 10:12:13  ->  2038-03-27T09:12:13Z   OK

2038-03-28 10:12:13  ->  2038-03-28T09:12:13Z   error : should be 2038-03-28 08:12:13Z

2038-10-30 10:12:13  ->  2038-10-30T09:12:13Z   error : should be 2038-10-30 08:12:13Z

2038-10-31 10:12:13  ->  2038-10-31T09:12:13Z   OK

PLEASE NOTE :
the date arithmetics seems not affected by the limit on unix timestamp (19/1/2018) since the following expressions work correctly :

$date = new DateTime();
$date->modify('+100 year');
echo $date->format('Y-m-d');

(It prints 2118-04-23)

Any suggestions ?
Regards maurizio

How to&Answers:

It is not a error. Nobody can predict the future.
If the summer time is abolished in the European Union in 2021,
then your values from 2022 to 2037 are wrong.
The PHP transitions list contains all offset changes for the time zone.
The last entry I see is “2037-10-25T01: 00: 00 + 0000”.

<?php
$tzRome = new DateTimeZone('Europe/Rome');
$transitionsList = $tzRome->getTransitions();
echo "<pre>";
var_dump($transitionsList);
echo "</pre>";