Error converting to UTC after 2038 on 64 bit unix PHP
Asked Answered
N

1

8

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

Ninetieth answered 23/4, 2018 at 9:17 Comment(2)
yes, nonsense. so there is no safe way to express, in utc, an expiration date of, say, 2040-7-20T00:00:00 Europe/Rome that should be expressed as 2040-7-19T22:00:00ZNinetieth
Possible duplicate of PHP DateTime setTimezone 2038Variorum
H
1

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>";
Halting answered 8/8, 2019 at 10:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.