Skip to content

timezone_identifiers_list(DateTimeZone::ALL_WITH_BC) Invalid timezones #18741

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

Closed
blaaat opened this issue Jun 2, 2025 · 4 comments
Closed

timezone_identifiers_list(DateTimeZone::ALL_WITH_BC) Invalid timezones #18741

blaaat opened this issue Jun 2, 2025 · 4 comments

Comments

@blaaat
Copy link

blaaat commented Jun 2, 2025

Description

The following code:

<?php
foreach (timezone_identifiers_list(DateTimeZone::ALL_WITH_BC) as $zone) {
        $timezone = new DateTimeZone($zone);
}

Resulted in this output:

PHP Fatal error:  Uncaught DateInvalidTimeZoneException: DateTimeZone::__construct(): Unknown or bad timezone (leapseconds) in /root/a.php:3
Stack trace:
#0 /root/a.php(3): DateTimeZone->__construct('leapseconds')

But I expected this output instead:

no error

my timezone_identifiers_list(DateTimeZone::ALL_WITH_BC) includes invalid timezones:

  • leapseconds
  • tzdata.zi

On a Rocky9 installation with php installation from remi repo: 8.3.21-1.el9.remi

PHP Version

PHP 8.3.21 (cli) (built: May  6 2025 13:58:10) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.3.21, Copyright (c) Zend Technologies
    with Zend OPcache v8.3.21, Copyright (c), by Zend Technologies

Operating System

Rocky Linux release 9.5 (Blue Onyx)

@nielsdos
Copy link
Member

nielsdos commented Jun 9, 2025

This doesn't reproduce for me. Do you have a different timezone database installed or loaded?

@blaaat
Copy link
Author

blaaat commented Jun 9, 2025

I have this tzdata installed:
tzdata.noarch 2025b-1.el9 @baseos

I can also reproduce this on Rocky Linux release 8.10 (Green Obsidian) (both php 8.3 and php 8.2)
Or on Ubuntu 24 / php 8.3

Already tried to install timezonedb using pecl,
timezonedb 2025.2 stable

But error doesn't go away.
Do you have suggestions of which information might be useful?

@hormus
Copy link

hormus commented Jun 9, 2025

tzdata.zi This zic input file is in the public domain. (Python).
https://docs.python.org/3/library/zoneinfo.html
https://peps.python.org/pep-0615/
However, there is still no support for the time zones described in the IANA time zone database (also called the “tz” database or the Olson database [6]).
Language C# (PHP 5.3 created constant DateTimeZone::ALL_WITH_BC) https://github.com/php/php-src/blob/PHP-5.3/ext/date/php_date.c#L4031
Can implement wrapper function for external timezonedb which use valid and invalid timezone ids like this (format Continent/City)

<?php
$copy = '' . check_id_allowed( 'Europe/Berlin' );
$copy = strtr( $copy, array( $copy => 'Europe/Berlin' , '0'  => '' ) );
$tz_identifiers = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC );
$key_valid = array_search( $copy, $tz_identifiers );
$copy = '';
if(is_int( $key_valid ) ) {
$copy = $copy . $tz_identifiers[$key_valid];
}
foreach($tz_identifiers as $value) {
if( check_id_allowed( $value ) ) {
echo $value;
}
}
echo $copy;
function check_id_allowed($id = 'UTC', $what = DateTimeZone::ALL)
{
	if ($what & DateTimeZone::AFRICA     && strncasecmp($id, "Africa/",      7) == 0) return DateTimeZone::AFRICA;
	if ($what & DateTimeZone::AMERICA    && strncasecmp($id, "America/",     8) == 0) return DateTimeZone::AMERICA;
	if ($what & DateTimeZone::ANTARCTICA && strncasecmp($id, "Antarctica/", 11) == 0) return DateTimeZone::ANTARCTICA;
	if ($what & DateTimeZone::ARCTIC     && strncasecmp($id, "Arctic/",      7) == 0) return DateTimeZone::ARTIC;
	if ($what & DateTimeZone::ASIA       && strncasecmp($id, "Asia/",        5) == 0) return DateTimeZone::ASIA;
	if ($what & DateTimeZone::ATLANTIC   && strncasecmp($id, "Atlantic/",    9) == 0) return DateTimeZone::ATLANTIC;
	if ($what & DateTimeZone::AUSTRALIA  && strncasecmp($id, "Australia/",  10) == 0) return DateTimeZone::AUSTRALIA;
	if ($what & DateTimeZone::EUROPE     && strncasecmp($id, "Europe/",      7) == 0) return DateTimeZone::EUROPE;
	if ($what & DateTimeZone::INDIAN     && strncasecmp($id, "Indian/",      7) == 0) return DateTimeZone::INDIAN;
	if ($what & DateTimeZone::PACIFIC    && strncasecmp($id, "Pacific/",     8) == 0) return DateTimeZone::PACIFIC;
	if ($what & DateTimeZone::UTC        && strncasecmp($id, "UTC",          3) == 0) return DateTimeZone::UTC;
	return 0;
}
?>

@nielsdos
Copy link
Member

nielsdos commented Jun 11, 2025

I can reproduce this in a ubuntu:24.04 container where I install php from the distro.
I can't reproduce this if I build PHP myself in that container.

I believe this indicates that something in how Ubuntu builds PHP changes the timezone database data...
And indeed it is the case! There's a patch 0007-Add-support-for-use-of-the-system-timezone-database.patch in the Debian and Ubuntu sources that adds a whole bunch of code to PHP ext/date to use the system timezone database. It's this patch that breaks.
TL;DR: it's a bug introduced by Debian's patches and should be reported to Debian/Ubuntu.
EDIT: They need to update their index_filter function in that patch.

@nielsdos nielsdos closed this as not planned Won't fix, can't repro, duplicate, stale Jun 11, 2025
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

3 participants