Skip to content

DateTimeZone::getTransitions() returns insufficient data #7752

Closed

Description

@mvorisek

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

Activity

  1. jellynoone commented on Dec 10, 2021

    @jellynoone
    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.

  2. cmb69 commented on Dec 10, 2021

    @cmb69
    Member

    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?

  3. iluuu1994 commented on Dec 10, 2021

    @iluuu1994
    Member

    https://3v4l.org/1Oe8V

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

  4. derickr commented on Dec 10, 2021

    @derickr
    Member

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

  5. changed the title [-]Datetime with 2203 year has a different timestamp in PHP 8.1[/-] [+]DateTimeZone::getTransitions() returns insufficient data[/+] on Dec 14, 2021
  6. DevSysEngineer commented on Feb 17, 2022

    @DevSysEngineer

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

  7. cmb69 commented on Feb 18, 2022

    @cmb69
    Member

    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?

  8. hormus commented on Mar 24, 2022

    @hormus

    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

  9. bobvandevijver commented on Mar 28, 2022

    @bobvandevijver

    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)
  10. derickr commented on Apr 1, 2022

    @derickr
    Member

    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.
  11. added a commit that references this issue on Apr 1, 2022
    e6c4988
  12. reloxx13 commented on May 5, 2023

    @reloxx13

    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.

  13. damianwadley commented on May 5, 2023

    @damianwadley
    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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions