php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #70701 Add support for seconds in timezone offset
Submitted: 2015-10-12 22:23 UTC Modified: 2022-06-05 13:40 UTC
Votes:7
Avg. Score:3.6 ± 1.3
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:2 (50.0%)
From: p at wspnr dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 7.0.0RC4 OS: All
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: p at wspnr dot com
New email:
PHP Version: OS:

 

 [2015-10-12 22:23 UTC] p at wspnr dot com
Description:
------------
The \DateTime and \DateTimeImmutable classes correctly handle timezone offsets of the format "-05" (hours) and "-05:30" (hours and minutes), but NOT "-05:30:30" (hours, minutes and seconds).

Given that the "Z" format code is available, presumably timezone offsets at this level of precision are supported.

The use case for this is interoperability with other applications. For instance, a timestamptz field in PostgreSQL 9.4 can have timezone offsets of this format.





Test script:
---------------
<?php

$dt1 = new \DateTime("2015-09-15 01:15-05:30");
echo $dt1->format("Y-m-d\TH:i:s.uZ");

$dt2 = new \DateTime("2015-09-15 01:15-05:30:30");
echo $dt2->format("Y-m-d\TH:i:s.uZ");

Expected result:
----------------
2015-09-15T01:15:00.000000-19800
2015-09-15T01:15:00.000000-19830

Actual result:
--------------
2015-09-15T01:15:00.000000-19800
Fatal error: Uncaught Exception: DateTime::__construct(): Failed to parse time string (2015-09-15 01:15-05:30:30) at position 22 (:): Unexpected character in /.../file.php

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-12 22:26 UTC] rasmus@php.net
But we don't have any timezones on this planet that has an offset that needs second granularity, do we? I wonder what the use case for this is in PostgreSQL?
 [2015-10-12 23:04 UTC] p at wspnr dot com
I had the same thought when it came up in testing, as it is not documented in the PostgreSQL docs. It seems to be some sort of fallback for ranges where PostgreSQL can't find the timezone data.

SELECT make_timestamptz(1895, 9, 15, 5, 30, 0.00, '-05:30:00');
=> "1895-09-15 06:00:00-05"

SELECT make_timestamptz(1894, 9, 15, 5, 30, 0.00, '-05:30:00');
=> "1894-09-15 05:42:28-05:17:32"

The problem arose because our testers entered '1111-11-11 11:11:11' as the date and time. PostgreSQL does this:

SELECT make_timestamptz(1111, 1, 11, 11, 11, 11.00, 'UTC');
=> "1111-11-11 05:53:39-05:17:32"

Tracing this further, it seems that PostgreSQL falls back to the system timezone if it can't make sense of the input. By default, the system timezone is 'localtime', which is equivalent to the entry in the zoneinfo database.

The zoneinfo database does express offsets with second precision:

Zone America/Toronto	-5:17:32 -	LMT	1895
 [2015-10-13 09:57 UTC] derick@php.net
PHP internally does support these second offset timezones. And Toronto is by no means the only locality with this "issue". For example:

<?php
date_default_timezone_set("Europe/Amsterdam");

$dt1 = new DateTimeImmutable("Wed Jun 30 23:59:59 1937");
echo $dt1->format(DateTime::ISO8601 . ' \i\n \s\e\c: Z'), "\n";

$dt2 = $dt1->modify("+1 second");
echo $dt2->format(DateTime::ISO8601 . ' \i\n \s\e\c: Z'), "\n";
?>

Produces:

1937-06-30T23:59:59+0119 in sec: 4772
1937-07-01T00:00:28+0120 in sec: 4800

However, the ISO 8601 standard that we use for parsing and formatting timezone offsets only allows "+hh:mm, +hhmm, or +hh" [1] and hence PHP doesn't understand parsing "2015-09-15 01:15-05:30:30". Unfortunately, the whole parser only caters for minute resolution here, and overhauling this is not going to be an easy feat.

[1] http://www.cl.cam.ac.uk/~mgk25/iso-time.html
 [2016-09-26 11:52 UTC] jan dot drabek at trigama dot eu
We encountered this bug when we developed application for timezone Europe/Luxembourg and used historic dates (1900-01-01 00:00:00) and we have found that at that times they used timezone with +00:24:36. (There is also another such timezone Paris Mean Time, see https://www.timeanddate.com/time/time-zones-history.html).

Also as p@wspnr.com thinks this is clearly a problem of interoperability, especially with PostgreSQL.
 [2017-03-19 11:57 UTC] heiglandreas@php.net
As the Olson-DB also contains the second-offset (https://github.com/eggert/tz/blob/c040ac6cb98d8c564a67e37468512d3e0447080b/europe#L1282) we should perhaps rethink about that, even though ISO only talks about HH:MM-Offset. But they don't specifically disallow the usage of seconds for offset…
 [2022-06-05 13:40 UTC] derick@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: derick
 [2022-06-05 13:40 UTC] derick@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.

This is now supported in Git master, for PHP 8.2, as bug #81565.

https://3v4l.org/Q8XHr/rfc#output
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 11:01:28 2024 UTC