php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74691 Novosibirsk Data Time Anomaly
Submitted: 2017-06-02 11:20 UTC Modified: 2017-06-07 20:13 UTC
From: karpulix at ya dot ru Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 7.1.5 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: karpulix at ya dot ru
New email:
PHP Version: OS:

 

 [2017-06-02 11:20 UTC] karpulix at ya dot ru
Description:
------------
Incorrect time interval in the Novosibirsk time zone. The problem is easy to reproduce on any server
----------------------
Некорректный интервал времени Новосибирском часовом поясе. Проблему легко воспроизвести на любом сервере

Test script:
---------------
$datetime_start = new DateTime('02.06.2015',new DateTimeZone("Europe/Moscow"));
$datetime_end = new DateTime('02.06.2017',new DateTimeZone("Europe/Moscow"));
print_r($datetime_end->getTimestamp() - $datetime_start->getTimestamp());
echo PHP_EOL;
$datetime_start = new DateTime('02.06.2015',new DateTimeZone("America/New_York"));
$datetime_end = new DateTime('02.06.2017',new DateTimeZone("America/New_York"));
print_r($datetime_end->getTimestamp() - $datetime_start->getTimestamp());
echo PHP_EOL;
$datetime_start = new DateTime('02.06.2015',new DateTimeZone("Asia/Novosibirsk"));
$datetime_end = new DateTime('02.06.2017',new DateTimeZone("Asia/Novosibirsk"));
print_r($datetime_end->getTimestamp() - $datetime_start->getTimestamp());
echo PHP_EOL;


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-06-02 11:29 UTC] derick@php.net
-Status: Open +Status: Feedback
 [2017-06-02 11:29 UTC] derick@php.net
Can you add the Actual and Expected output please?
 [2017-06-02 11:33 UTC] derick@php.net
-Status: Feedback +Status: Not a bug
 [2017-06-02 11:33 UTC] derick@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Actually, I see what happens.

There is no bug.

Unlike Moscow and New_York, Novosibirsk changed GMT offsets between June 2nd,2015 and June 2nd, 2017.

Moscow:
Europe/Moscow  Sat Mar 26 23:00:00 2011 UT = Sun Mar 27 03:00:00 2011 MSK isdst=0 gmtoff=14400
Europe/Moscow  Sat Oct 25 21:59:59 2014 UT = Sun Oct 26 01:59:59 2014 MSK isdst=0 gmtoff=14400
Europe/Moscow  Sat Oct 25 22:00:00 2014 UT = Sun Oct 26 01:00:00 2014 MSK isdst=0 gmtoff=10800

(Last change was in 2014 to UTC+3)

New York
UTC+3

Novosibirsk:

Asia/Novosibirsk  Sat Mar 26 20:00:00 2011 UT = Sun Mar 27 03:00:00 2011 +07 isdst=0 gmtoff=25200
Asia/Novosibirsk  Sat Oct 25 18:59:59 2014 UT = Sun Oct 26 01:59:59 2014 +07 isdst=0 gmtoff=25200
Asia/Novosibirsk  Sat Oct 25 19:00:00 2014 UT = Sun Oct 26 01:00:00 2014 +06 isdst=0 gmtoff=21600
Asia/Novosibirsk  Sat Jul 23 19:59:59 2016 UT = Sun Jul 24 01:59:59 2016 +06 isdst=0 gmtoff=21600
Asia/Novosibirsk  Sat Jul 23 20:00:00 2016 UT = Sun Jul 24 03:00:00 2016 +07 isdst=0 gmtoff=25200

UTC+6 in 2015, and UTC+7 in 2017. That's why you get the 3600 seconds difference.
 [2017-06-02 12:14 UTC] karpulix at ya dot ru
Because of this, the method works incorrectly "diff" from "DateTime class"
-----
Из-за этого неверно работает метод "diff" класса DateTime


//correct:
$dataTimeZone = new DateTimeZone("Europe/Moscow");
    $datetime = new DateTime('02.06.2015',$dataTimeZone);
    $now = new DateTime('02.06.2017',$dataTimeZone);
    $interval = $datetime->diff($now);
    $fullYear = (int)$interval->format("%Y");
echo $fullYear;
// 2 - its correct

//incorrect
$dataTimeZone = new DateTimeZone("Asia/Novosibirsk");
    $datetime = new DateTime('02.06.2015',$dataTimeZone);
    $now = new DateTime('02.06.2017',$dataTimeZone);
    $interval = $datetime->diff($now);
    $fullYear = (int)$interval->format("%Y");
echo $fullYear;
// 1 - its incorrect
 [2017-06-04 07:53 UTC] heiglandreas@php.net
The diff method works pretty well, you are only looking at a fraction of the result though.

When you look at https://3v4l.org/6eiD6 you will notice that the difference is 1 year, 11 months, 30 days and 23 hours. Due to the DST-change it's 1 hour short of being two years!
 [2017-06-04 08:12 UTC] karpulix at ya dot ru
But in fact diff does not provide the data correctly. Maybe need to fix the problem at the level of the environment?
-----------
Но фактически diff предоставляет  неверные данные. Может быть нужно исправлять проблему на уровне окружения?
 [2017-06-04 08:58 UTC] heiglandreas@php.net
Why do you think the diff doesn't provide the data correctly? After all there IS one hour missing in the diff. 

You might want something different from it but that's a different story. The difference between anytime on the 2nd of June 2015 in "Asia/Novosibirsk" and the same time on the 2nd of June 2017 in Asia/Novosibirsk is 1 year, 11 months, 30 days and 23 hours. 

So I'd really be interested why you think it doesn't "provide the data correctly"
 [2017-06-06 05:56 UTC] karpulix at ya dot ru
Because regardless of the time zone in the period beetween from 02.06.2015 to 02.06.2017  should be the same number of seconds. This is an axiom. No?
------------
Потому что независимо от часового пояса в промежутке от 02.06.2015 до 02.06.2017 должно быть одинаковое количество секунд. Это аксиома.
 [2017-06-07 20:13 UTC] heiglandreas@php.net
No. It's not. Due to the Timezone change there where about 3600 seconds less than you are expecting…
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 14:01:30 2024 UTC