rfc:datetime_and_daylight_saving_time

This is an old revision of the document!


Request for Comments: DateTime and Daylight Saving Time Transitions

Introduction

PHP's DateTime class has unexpected outcomes when dealing with the transitions between Daylight Saving Time and Standard Time.

Properly defining, documenting and unit testing DateTime's behaviors is important for PHP's future. This document seeks agreement on what the expected behaviors should be.

Getting these issues straightened out before 5.4 goes into Release Candidate status seems wise.

Time Zone for Sake of Discussion

The America/New_York time zone will be used as the basis for this discussion. The Standard/Daylight transition in this zone happens at 2:00 am. The forward transition (in spring) jumps to 3:00 am, skipping over the hour of 2 am. The backward transition (in fall) jumps back to 1:00 am, repeating the hour of 1am.

Other zones use different transition quantities and times.

Construction During Transitions

Forward Transitions

Times between 2:00:00 am and 2:59:59 am do not exist during the Forward Transitions transition. Attempts to create such times should be rounded forward, like PHP currently does when trying to create February 29th on a non-leap year.

date_default_timezone_set('America/New_York');
$date = new DateTime('2010-03-14 02:30:00');
echo $date->format('Y-m-d H:i:s T') . "\n";
// Expected: 2010-03-14 03:30:00 EDT
// Actual:   2010-03-14 02:30:00 EDT

Backward Transitions

PHP needs a means to create objects representing times during the hour repeated on the Daylight/Standard transition day (between 1:00:00 am and 1:59:59 am Standard Time).

This RFC proposes adjusting the time string parser to handle strings ending in DST and ST. When DST or ST are not present, PHP will use the current behavior, which uses the time zone offset in place at the specified time and uses DST offset during the repeated hour during backward transitions.

Force Daylight Saving Time:

date_default_timezone_set('America/New_York');
$date = new DateTime('2010-11-07 01:30:00 DST');
echo $date->format('Y-m-d H:i:s T') . "\n";
// Expected: 2010-11-07 01:30:00 EDT

Force Standard Time:

date_default_timezone_set('America/New_York');
$date = new DateTime('2010-11-07 01:30:00 ST');
echo $date->format('Y-m-d H:i:s T') . "\n";
// Expected: 2010-11-07 01:30:00 EST

Default to Daylight Time during repeated hour, PHP's current behavior:

date_default_timezone_set('America/New_York');
$date = new DateTime('2010-11-07 01:30:00');
echo $date->format('Y-m-d H:i:s T') . "\n";
// Expected & Actual: 2010-11-07 01:30:00 EDT

Attempts to create a time that is during Daylight Saving Time but using ST should roll the time forward to Daylight Saving Time. Attempts to create a time that is during Standard Time but using DST should roll the time back to Standard Time.

Math

Forward Transitions

diff()

End Start Expected Result Currently Works
2010-03-14 03:00:00 EDT 2010-03-14 01:59:59 EST PT0H0M1S N
2010-03-14 04:30:00 EDT 2010-03-13 04:30:00 EST P1DT0H Y
2010-03-14 03:30:00 EDT 2010-03-13 04:30:00 EST P0DT22H N
2010-03-14 01:30:00 EST 2010-03-13 04:30:00 EST P0DT21H Y
2010-03-14 01:30:00 EST 2010-03-13 01:30:00 EST P1DT0H Y

add()

Start Interval Expected Result Currently Works
2010-03-14 01:59:59 EST PT1S 2010-03-14 03:00:00 EDT Y
2010-03-13 04:30:00 EST P1D 2010-03-14 04:30:00 EDT Y
2010-03-13 04:30:00 EST PT22H 2010-03-14 03:30:00 EDT Y
2010-03-13 04:30:00 EST PT21H 2010-03-14 01:30:00 EST Y
2010-03-13 01:30:00 EST P1D 2010-03-14 01:30:00 EST Y
2010-03-13 02:30:00 EST P1D 2010-03-14 02:30:00 EDT Y

sub()

End Interval Expected Result Currently Works
2010-03-14 03:00:00 EDT PT1S 2010-03-14 01:59:59 EST N
2010-03-14 04:30:00 EDT P1D 2010-03-13 04:30:00 EST Y
2010-03-14 03:30:00 EDT PT22H 2010-03-13 04:30:00 EST N
2010-03-14 01:30:00 EST PT21H 2010-03-13 04:30:00 EST Y
2010-03-14 01:30:00 EST P1D 2010-03-13 01:30:00 EST Y

Backward Transitions

diff()

End Start Expected Result Currently Works
2010-11-07 01:00:00 EST 2010-11-07 01:59:59 EDT PT0H0M1S N
2010-11-07 04:30:00 EST 2010-11-06 04:30:00 EDT P1DT0H Y
2010-11-07 03:30:00 EST 2010-11-06 04:30:00 EDT P0DT24H N
2010-11-07 02:30:00 EST 2010-11-06 04:30:00 EDT P0DT23H N
2010-11-07 01:30:00 EST 2010-11-06 04:30:00 EDT P0DT22H N
2010-11-07 01:30:00 EDT 2010-11-06 04:30:00 EDT P0DT21H Y
2010-11-07 01:30:00 EDT 2010-11-06 01:30:00 EDT P1DT0H Y
2010-11-07 01:30:00 EST 2010-11-06 01:30:00 EDT P1DT1H N

add()

Start Interval Expected Result Currently Works
2010-11-07 01:59:59 EDT PT1S 2010-11-07 01:00:00 EST N
2010-11-06 04:30:00 EDT P1D 2010-11-07 04:30:00 EST Y
2010-11-06 04:30:00 EDT PT24H 2010-11-07 03:30:00 EST N
2010-11-06 04:30:00 EDT PT23H 2010-11-07 02:30:00 EST N
2010-11-06 04:30:00 EDT PT22H 2010-11-07 01:30:00 EST N
2010-11-06 04:30:00 EDT PT21H 2010-11-07 01:30:00 EDT Y
2010-11-06 01:30:00 EDT P1D 2010-11-07 01:30:00 EDT Y
2010-11-06 01:30:00 EDT P1DT1H 2010-11-07 01:30:00 EST N

sub()

End Interval Expected Result Currently Works
2010-11-07 01:00:00 EST PT1S 2010-11-07 01:59:59 EDT N
2010-11-07 04:30:00 EST P1D 2010-11-06 04:30:00 EDT Y
2010-11-07 03:30:00 EST PT24H 2010-11-06 04:30:00 EDT N
2010-11-07 02:30:00 EST PT23H 2010-11-06 04:30:00 EDT N
2010-11-07 01:30:00 EST PT22H 2010-11-06 04:30:00 EDT N
2010-11-07 01:30:00 EDT PT21H 2010-11-06 04:30:00 EDT Y
2010-11-07 01:30:00 EDT P1D 2010-11-06 01:30:00 EDT Y
2010-11-07 01:30:00 EST P1DT1H 2010-11-06 01:30:00 EDT N

Other Issues?

If you know of other problems, please add them here or bring them to the attention of the authors.

Changelog

rfc/datetime_and_daylight_saving_time.1314240409.txt.gz · Last modified: 2017/09/22 13:28 (external edit)