Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTimeZone::getTransitions() returns insufficient data #7752

Closed
mvorisek opened this issue Dec 10, 2021 · 11 comments
Closed

DateTimeZone::getTransitions() returns insufficient data #7752

mvorisek opened this issue Dec 10, 2021 · 11 comments

Comments

@mvorisek
Copy link
Contributor

Description

The following code:

var_dump(
    (new \DateTime('2203-10-05 15:05:37.180157', new \DateTimeZone('America/Los_Angeles')))
    ->getTimestamp()
);

https://3v4l.org/HpVAr

produces different result on PHP 8.1 vs PHP 7.4/8.0

it is from our failing unit test, what result is correct and any plain to bugfix in either PHP 8.1 or the PHP 8.0 and lower?

PHP Version

PHP 8.1.0

Operating System

linux

@jellynoone
Copy link
Contributor

It seems the bug starts with 2100-03-14 03:00:00 while 2100-03-14 02:59:59 works fine.

On PHP 8.1 2100-03-14 03:00:00 under the America/Los_Angeles time zone has the same timestamp as2100-03-14 02:00:00.

@cmb69
Copy link
Contributor

cmb69 commented Dec 10, 2021

It seems that transitions are not tracked far in the future, and that neither version is totally correct; apparently, prior to PHP 8.1.0 DST was always assumed, while as of PHP 8.1.0 standard time is assumed (what would make more sense).

@derickr, can you please clarify?

@iluuu1994
Copy link
Member

iluuu1994 commented Dec 10, 2021

https://3v4l.org/1Oe8V

All transitions in the future except for the next seem to be gone. (might be by design, not sure)

@derickr
Copy link
Contributor

derickr commented Dec 10, 2021

I'm going to have to check this, as the new code should definitely handle this correctly.

@cmb69 cmb69 changed the title Datetime with 2203 year has a different timestamp in PHP 8.1 DateTimeZone::getTransitions() returns insufficient data Dec 14, 2021
@DevSysEngineer
Copy link

Can some one tell when this issue will be fixed? We added now hacks in our code base for getting now the correct timestamp.

@cmb69
Copy link
Contributor

cmb69 commented Feb 18, 2022

There is apparently something wrong with reading the timezone DB in PHP 8.1. Although both have identical timezonedb.h files, for America/Los_Angeles, PHP 8.0 reads timelib_tzinfo->64bit.timecnt == 186, while PHP 8.1 reads timelib_tzinfo->64bit.timecnt == 125.

@derickr, any idea what change in timelib may have caused this?

@hormus
Copy link

hormus commented Mar 24, 2022

I'm going to have to check this, as the new code should definitely handle this correctly.

https://bugs.php.net/bug.php?id=80963
It's broken.
@CMB @derickr without if !isset($is_dst) || !$is_dst
https://3v4l.org/es6E4

@bobvandevijver
Copy link

bobvandevijver commented Mar 28, 2022

Interestingly, I'm seeing different results with different installations. Consider the following command:

php -r "var_dump((new \DateTimeZone('Europe/Amsterdam'))->getTransitions(1593186495, 1711813695));"

It returns 7 records on:

  • php:8.0 (docker)
  • 8.1.4 sury debian install

It returns 1 record on:

  • php:8.1 (docker)

@derickr
Copy link
Contributor

derickr commented Apr 1, 2022

Hi, there are bunch of things going on here.

  • First of all, the PHP 8.1.x result is correct in @mvorisek example.
  • Before PHP 8.1, transitions were only tracked until 2100. Anything after that, used the last rule. For Los_Angeles, that would have been UTC-8 (incorrectly).
  • In PHP 8.1 and later, timelib has implemented support for POSIX TZ strings, which allow to calculate transitions with the existing rules.
  • Operating Systems changed their tzdata format from "fat" to "small", and the latter only includes transitions up until the last change in DST rules. For anything beyond that, POSIX TZ strings must now be used. (This explains the discrepancies between different distributions of the same PHP version)
  • This means that it can now knows about DST in 2203, where UTC-7 applies: string(25) "2203-10-05T15:05:37-07:00"
  • @iluuu1994's comment (DateTimeZone::getTransitions() returns insufficient data #7752 (comment)) is indeed a bug, in where transitions were not returned if an initial timestamp was passed to getTransions, which lay after the last transition (from the slim files). It is likely the same issue as in PHP 8.1 Timezone doesn't work as intended #8108.

@derickr derickr closed this as completed in e6c4988 Apr 1, 2022
@reloxx13
Copy link

reloxx13 commented May 5, 2023

How many years left for the 8.2.6 release including this important bug fix for date/time?

UTC->Europe/Berlin
7.4 date correct (5.5.2023)
7.4 -> 8.1.5 = date wrong (6.5.2023)
7.4 -> 8.0.25 = date correct (6.5.2023)

You are producing so many headaches, work and money lost by not releasing the fix for over a year for many companies.

@damianwadley
Copy link
Member

@reloxx13 The bug reported here was fixed. If you think you have a new bug then create a new issue for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

12 participants