php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76624 date_create_from_format doesn't respect "T" Timezone format character
Submitted: 2018-07-14 20:39 UTC Modified: 2018-07-15 14:50 UTC
From: jalaj dot chhalotre at gmail dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 7.0.30 OS: Ubuntu 16.04.1
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: jalaj dot chhalotre at gmail dot com
New email:
PHP Version: OS:

 

 [2018-07-14 20:39 UTC] jalaj dot chhalotre at gmail dot com
Description:
------------
When T timezone format character is used to specify timezone in date_create_from_format() function, wrong time (with respect to epoch) is generated.
In test script attached, two different epoch times are generated if 'T' and 'e' timezone format characters are used. However using e format character returns correct time.

Test script:
---------------
# date_string = "2018-07-13 15:30:15 IST" = "2018-07-13 15:30:15 Asia/Kolkata"

$date1 = new DateTime('2018-07-13 15:30:15', new DateTimeZone('Asia/Kolkata'));
echo $date1->format('Y-m-d H:i:s T');
//2018-07-13 15:30:15 IST

echo $str1=$date1->format('U');
//1531476015
$date2=date_create_from_format('Y-m-d H:i:s T', '2018-07-13 15:30:15 IST');
echo $str2=$date2->format('U');
//1531488615

/*
$str1 IS NOT equal to $str2
but date1=date2
*/

echo $date1->format('Y-m-d H:i:s e');
//2018-07-13 15:30:15 Asia/Kolkata

echo $str3=$date1->format('U');
//1531476015
$date2=date_create_from_format('Y-m-d H:i:s e', '2018-07-13 15:30:15 Asia/Kolkata');
echo $str4=$date2->format('U');
//1531476015

/*
$str3 IS equal to $str4
as date1=date3
*/


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-07-14 20:43 UTC] jalaj dot chhalotre at gmail dot com
-Operating System: Ubuntu 0.16.04.1 +Operating System: Ubuntu 16.04.1
 [2018-07-14 20:43 UTC] jalaj dot chhalotre at gmail dot com
Corrected OS (typo)
 [2018-07-14 21:30 UTC] cmb@php.net
-Package: *General Issues +Package: Date/time related
 [2018-07-15 08:07 UTC] jalaj dot chhalotre at gmail dot com
Noticed this bug is timezone dependent, e.g. if TimeZone is CDT (Canada/Central) the difference in epoch of mentioned function is 0. On the other side IST, CST(China Standard time) result in epoch difference.

Created a test function to check variability of this bug with timezone.
<?php
bug_epoch_diff('2018-07-13 15:30:15','Asia/Shanghai');
bug_epoch_diff('2018-07-13 15:30:15','Asia/Kolkata');
bug_epoch_diff('2018-07-13 15:30:15','Asia/Hong_Kong');
bug_epoch_diff('2018-07-13 15:30:15','Asia/Macau');
bug_epoch_diff('2018-07-13 15:30:15','Asia/Macau'); 
bug_epoch_diff('2018-07-13 15:30:15','Canada/Central');
bug_epoch_diff('2018-07-13 15:30:15','Brazil/Acre');
bug_epoch_diff('2018-07-13 15:30:15','Europe/Berlin');


function bug_epoch_diff($datetime,$timezone){
// date='2018-07-13 15:30:15' TimeZone='Asia/Kolkata'
$date = new DateTime($datetime, new DateTimeZone($timezone));
echo "DateTime in format 'Y-m-d H:i:s T': ". $date->format('Y-m-d H:i:s T');
echo " | ";
echo $ep1=$date->format('U');
echo " | ";
//1531476015
echo $ep2=date_create_from_format('Y-m-d H:i:s T', $date->format('Y-m-d H:i:s T'))->format('U');
//1531488615
echo " | ";

//Comment: for same date two different epoch
echo "Epoch difference for ".$timezone."=".(((float)$ep2)-((float)$ep1))."<br>";
}
?>
_____
Output:
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 CST | 1531467015 | 1531517415 | Epoch difference for Asia/Shanghai=50400
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 IST | 1531476015 | 1531488615 | Epoch difference for Asia/Kolkata=12600
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 HKT | 1531467015 | 1531467015 | Epoch difference for Asia/Hong_Kong=0
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 CST | 1531467015 | 1531517415 | Epoch difference for Asia/Macau=50400
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 CST | 1531467015 | 1531517415 | Epoch difference for Asia/Macau=50400
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 CDT | 1531513815 | 1531513815 | Epoch difference for Canada/Central=0
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 -05 | 1531513815 | 1531513815 | Epoch difference for Brazil/Acre=0
DateTime in format 'Y-m-d H:i:s T': 2018-07-13 15:30:15 CEST | 1531488615 | 1531488615 | Epoch difference for Europe/Berlin=0
 [2018-07-15 09:56 UTC] a at b dot c dot de
What timezone does IST name? Jerusalem, Kolkata, or Dublin?

<?php

$date2=date_create_from_format('Y-m-d H:i:s T', '2018-07-13 15:30:15 IST');
echo $date2->format('Y-m-d H:i:s e (T)'),"\t", $date2->format('U'),"\n";
echo "\n";
foreach(array_column(DateTimeZone::listAbbreviations()['ist'], 'timezone_id') as $tz)
{
	$date1 = new DateTime('2018-07-13 15:30:15', new DateTimeZone($tz));
	echo $date1->format('Y-m-d H:i:s e (T)'),"\t", $date1->format('U'),"\n";
}


Apparently it's interpreted as Israel Standard Time.

Suggest you avoid the ambiguity and stick with using "Asia/Kolkata".

$date2=date_create_from_format('Y-m-d H:i:s T', '2018-07-13 15:30:15 Asia/Kolkata');
echo $date2->format('Y-m-d H:i:s e (T)'),"\t", $date2->format('U'),"\n";
 [2018-07-15 10:06 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2018-07-15 10:06 UTC] requinix@php.net
Well spotted, @a.

Indeed, there are three different "IST" timezones. Abbreviations are not unique.
https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
 [2018-07-15 13:23 UTC] jalaj dot chhalotre at gmail dot com
Oh ok, Thanks for highlighting Israel in IST.
However my two observations:
1. Inconsitency is not specific to IST, for other timezones as well as mentioned in my previous comment.
2. When existing date formatted with T, Asia/Kolkata is printed as IST, but when date is created with mentioned function and format T, IST is interpreted as Israel time. Isn't it be canonical.

My suggestion - if there are multiple representations, T format should output difference with UTC e.g. +5:30. The same way T format does for "Brazil/Acre" timezone.
 [2018-07-15 14:50 UTC] requinix@php.net
Any timezone abbreviation that is not unique will result in undefined behavior if you try to create a time using it. IST has three meanings. CST has three meanings. CDT has two meanings.

Do not create a time using those abbreviations and expect PHP to correctly guess which timezone you meant.

If you want to see the UTC offset like +05:30 then use the 'P' format. But you still must not use the abbreviation.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 01:01:30 2024 UTC