php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71913 extra hour in DateTime modify (Daylight Saving Time problem)
Submitted: 2016-03-29 09:07 UTC Modified: 2016-03-29 09:33 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: public at RTLer dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 7.0.4 OS: Ubuntu 14.04.4 LTS (GNU/Linux 3.
Private report: No CVE-ID: None
 [2016-03-29 09:07 UTC] public at RTLer dot com
Description:
------------
i use php library "Carbon/Carbon" witch use DateTime directly 
and when i add one day to this exact day "2016-03-20" with timezone of "Asia/Tehran" it give one extra hour
but when i add two day it works just fine.

Test script:
---------------
$timezone = new DateTimeZone('Asia/Tehran');
$dayStart = new DateTime('2016-03-20 00:00:00.000000', $timezone);

$dayOne = (new DateTime('2016-03-20 00:00:00.000000', $timezone))->modify('1 day');
$dayTwo = (new DateTime('2016-03-20 00:00:00.000000', $timezone))->modify('2 day');


echo json_encode([
    '$dayStart' => $dayStart,
    '$dayOne' => $dayOne,
    'diff of $dayOne' => $dayStart->diff($dayOne,true),
    '$dayTwo' => $dayTwo,
    'diff of $dayTwo' => $dayStart->diff($dayTwo,true),
]);
die;

Expected result:
----------------
{
    "$dayStart": {
        "date": "2016-03-20 00:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "$dayOne": {
        "date": "2016-03-21 00:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "diff of $dayOne": {
        "y": 0,
        "m": 0,
        "d": 1,
        "h": 0,
        "i": 0,
        "s": 0,
        "weekday": 0,
        "weekday_behavior": 0,
        "first_last_day_of": 0,
        "invert": 0,
        "days": 1,
        "special_type": 0,
        "special_amount": 0,
        "have_weekday_relative": 0,
        "have_special_relative": 0
    },
    "$dayTwo": {
        "date": "2016-03-22 00:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "diff of $dayTwo": {
        "y": 0,
        "m": 0,
        "d": 2,
        "h": 0,
        "i": 0,
        "s": 0,
        "weekday": 0,
        "weekday_behavior": 0,
        "first_last_day_of": 0,
        "invert": 0,
        "days": 2,
        "special_type": 0,
        "special_amount": 0,
        "have_weekday_relative": 0,
        "have_special_relative": 0
    }
}

Actual result:
--------------
{
    "$dayStart": {
        "date": "2016-03-20 00:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "$dayOne": {
        "date": "2016-03-21 01:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "diff of $dayOne": {
        "y": 0,
        "m": 0,
        "d": 1,
        "h": 1,
        "i": 0,
        "s": 0,
        "weekday": 0,
        "weekday_behavior": 0,
        "first_last_day_of": 0,
        "invert": 0,
        "days": 1,
        "special_type": 0,
        "special_amount": 0,
        "have_weekday_relative": 0,
        "have_special_relative": 0
    },
    "$dayTwo": {
        "date": "2016-03-22 00:00:00.000000",
        "timezone_type": 3,
        "timezone": "Asia\/Tehran"
    },
    "diff of $dayTwo": {
        "y": 0,
        "m": 0,
        "d": 2,
        "h": 0,
        "i": 0,
        "s": 0,
        "weekday": 0,
        "weekday_behavior": 0,
        "first_last_day_of": 0,
        "invert": 0,
        "days": 2,
        "special_type": 0,
        "special_amount": 0,
        "have_weekday_relative": 0,
        "have_special_relative": 0
    }
}

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-03-29 09:12 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2016-03-29 09:12 UTC] requinix@php.net
Asia/Tehran did not have a 2016-03-21 00:00:00 because of the start of daylight savings. 01:00:00 is the most logical result.
It did have a 2016-03-22 00:00:00 so that is as expected.
 [2016-03-29 09:33 UTC] derick@php.net
This is because "March 21st, 00:00" does not exist, but "March 22nd, 00:00" does exist. Because "March 21st, 00:00" to "00:59" do not exist, the library skips to "01:00" - this is on purpose.

However, you can argue that the *diff* between $dayStart and $dayOne should be "1 day" too. The RFC in https://wiki.php.net/rfc/datetime_and_daylight_saving_time describes what should happen in that case.
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Tue Oct 06 12:00:01 2026 UTC