mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge remote-tracking branch 'derickr/fix-datetime-diff-around-dst-transition' into PHP-8.2
This commit is contained in:
commit
d1af263dd9
4 changed files with 40 additions and 93 deletions
|
@ -36,25 +36,6 @@ static void swap_times(timelib_time **one, timelib_time **two, timelib_rel_time
|
|||
rt->invert = 1;
|
||||
}
|
||||
|
||||
static void swap_if_negative(timelib_rel_time *rt)
|
||||
{
|
||||
if (rt->y == 0 && rt->m == 0 && rt->d == 0 && rt->h == 0 && rt->i == 0 && rt->s == 0 && rt->us == 0) {
|
||||
return;
|
||||
}
|
||||
if (rt->y >= 0 && rt->m >= 0 && rt->d >= 0 && rt->h >= 0 && rt->i >= 0 && rt->s >= 0 && rt->us >= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
rt->invert = 1 - rt->invert;
|
||||
rt->y = 0 - rt->y;
|
||||
rt->m = 0 - rt->m;
|
||||
rt->d = 0 - rt->d;
|
||||
rt->h = 0 - rt->h;
|
||||
rt->i = 0 - rt->i;
|
||||
rt->s = 0 - rt->s;
|
||||
rt->us = 0 - rt->us;
|
||||
}
|
||||
|
||||
static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_time *rt)
|
||||
{
|
||||
/* Check whether date/times need to be inverted. If both times are
|
||||
|
@ -115,80 +96,48 @@ static timelib_rel_time *timelib_diff_with_tzid(timelib_time *one, timelib_time
|
|||
rt->days = timelib_diff_days(one, two);
|
||||
|
||||
/* Fall Back: Cater for transition period, where rt->invert is 0, but there are negative numbers */
|
||||
if (one->dst == 1 && two->dst == 0) {
|
||||
/* First for two "Type 3" times */
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
if (
|
||||
success &&
|
||||
one->sse < trans_transition_time &&
|
||||
one->sse >= trans_transition_time + dst_corr
|
||||
) {
|
||||
timelib_sll flipped = SECS_PER_HOUR + (rt->i * 60) + (rt->s);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
}
|
||||
} else if (rt->h == 0 && (rt->i < 0 || rt->s < 0)) {
|
||||
/* Then for all the others */
|
||||
timelib_sll flipped = SECS_PER_HOUR + (rt->i * 60) + (rt->s);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
dst_corr += SECS_PER_HOUR;
|
||||
dst_h_corr++;
|
||||
}
|
||||
if (two->sse < one->sse) {
|
||||
timelib_sll flipped = llabs((rt->i * 60) + (rt->s) - dst_corr);
|
||||
rt->h = flipped / SECS_PER_HOUR;
|
||||
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
|
||||
rt->s = flipped % 60;
|
||||
|
||||
rt->invert = 1 - rt->invert;
|
||||
}
|
||||
|
||||
timelib_do_rel_normalize(rt->invert ? one : two, rt);
|
||||
|
||||
/* Do corrections for "Type 3" times with the same TZID */
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID && strcmp(one->tz_info->name, two->tz_info->name) == 0) {
|
||||
if (one->dst == 1 && two->dst == 0) { /* Fall Back */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
if (
|
||||
success &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (one->dst == 0 && two->dst == 1) { /* Spring Forward */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
if (
|
||||
success &&
|
||||
!((one->sse + SECS_PER_DAY > trans_transition_time) && (one->sse + SECS_PER_DAY <= (trans_transition_time + dst_corr))) &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (two->sse - one->sse >= SECS_PER_DAY) {
|
||||
/* Check whether we're in the period to the next transition time */
|
||||
if (timelib_get_time_zone_offset_info(two->sse - two->z, two->tz_info, &trans_offset, &trans_transition_time, NULL)) {
|
||||
dst_corr = one->z - trans_offset;
|
||||
|
||||
if (two->sse >= trans_transition_time - dst_corr && two->sse < trans_transition_time) {
|
||||
rt->d--;
|
||||
rt->h = 24;
|
||||
}
|
||||
if (one->dst == 1 && two->dst == 0) { /* Fall Back */
|
||||
if (two->tz_info) {
|
||||
if ((two->sse - one->sse + dst_corr) < SECS_PER_DAY) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
} else if (one->dst == 0 && two->dst == 1) { /* Spring Forward */
|
||||
if (two->tz_info) {
|
||||
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL);
|
||||
|
||||
swap_if_negative(rt);
|
||||
if (
|
||||
success &&
|
||||
!((one->sse + SECS_PER_DAY > trans_transition_time) && (one->sse + SECS_PER_DAY <= (trans_transition_time + dst_corr))) &&
|
||||
two->sse >= trans_transition_time &&
|
||||
((two->sse - one->sse + dst_corr) % SECS_PER_DAY) > (two->sse - trans_transition_time)
|
||||
) {
|
||||
rt->h -= dst_h_corr;
|
||||
rt->i -= dst_m_corr;
|
||||
}
|
||||
}
|
||||
} else if (two->sse - one->sse >= SECS_PER_DAY) {
|
||||
/* Check whether we're in the period to the next transition time */
|
||||
if (timelib_get_time_zone_offset_info(two->sse - two->z, two->tz_info, &trans_offset, &trans_transition_time, NULL)) {
|
||||
dst_corr = one->z - trans_offset;
|
||||
|
||||
timelib_do_rel_normalize(rt->invert ? one : two, rt);
|
||||
if (two->sse >= trans_transition_time - dst_corr && two->sse < trans_transition_time) {
|
||||
rt->d--;
|
||||
rt->h = 24;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rt;
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
# include "timelib_config.h"
|
||||
#endif
|
||||
|
||||
#define TIMELIB_VERSION 202205
|
||||
#define TIMELIB_EXTENDED_VERSION 20220501
|
||||
#define TIMELIB_ASCII_VERSION "2022.05"
|
||||
#define TIMELIB_VERSION 202206
|
||||
#define TIMELIB_EXTENDED_VERSION 20220601
|
||||
#define TIMELIB_ASCII_VERSION "2022.06"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
DateTime::diff() -- fall type3 type3
|
||||
--CREDITS--
|
||||
Daniel Convissor <danielc@php.net>
|
||||
--XFAIL--
|
||||
Various bugs exist
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
|
@ -30,7 +28,7 @@ test_time_fall_type3_redodt_type3_dt: DIFF: 2010-11-07 00:10:20 EDT - 2010-11-07
|
|||
test_time_fall_type3_redodt_type3_redodt: DIFF: 2010-11-07 01:15:35 EDT - 2010-11-07 01:12:33 EDT = **P+0Y0M0DT0H3M2S**
|
||||
test_time_fall_type3_redodt_type3_redost: DIFF: 2010-11-07 01:14:44 EST - 2010-11-07 01:12:33 EDT = **P+0Y0M0DT1H2M11S**
|
||||
test_time_fall_type3_redodt_type3_st: DIFF: 2010-11-07 03:16:55 EST - 2010-11-07 01:12:33 EDT = **P+0Y0M0DT3H4M22S**
|
||||
test_time_fall_type3_redodt_type3_post: DIFF: 2010-11-08 19:59:59 EST - 2010-11-07 01:12:33 EDT = **P+0Y0M1DT19H47M26S**
|
||||
test_time_fall_type3_redodt_type3_post: DIFF: 2010-11-08 19:59:59 EST - 2010-11-07 01:12:33 EDT = **P+0Y0M1DT18H47M26S**
|
||||
test_time_fall_type3_redost_type3_prev: DIFF: 2010-11-06 18:38:28 EDT - 2010-11-07 01:14:44 EST = **P-0Y0M0DT7H36M16S**
|
||||
test_time_fall_type3_redost_type3_dt: DIFF: 2010-11-07 00:10:20 EDT - 2010-11-07 01:14:44 EST = **P-0Y0M0DT2H4M24S**
|
||||
test_time_fall_type3_redost_type3_redodt: DIFF: 2010-11-07 01:12:33 EDT - 2010-11-07 01:14:44 EST = **P-0Y0M0DT1H2M11S**
|
||||
|
@ -45,7 +43,7 @@ test_time_fall_type3_st_type3_st: DIFF: 2010-11-07 05:19:56 EST - 2010-11-07 03:
|
|||
test_time_fall_type3_st_type3_post: DIFF: 2010-11-08 19:59:59 EST - 2010-11-07 03:16:55 EST = **P+0Y0M1DT16H43M4S**
|
||||
test_time_fall_type3_post_type3_prev: DIFF: 2010-11-06 18:38:28 EDT - 2010-11-08 19:59:59 EST = **P-0Y0M2DT1H21M31S**
|
||||
test_time_fall_type3_post_type3_dt: DIFF: 2010-11-07 00:10:20 EDT - 2010-11-08 19:59:59 EST = **P-0Y0M1DT19H49M39S**
|
||||
test_time_fall_type3_post_type3_redodt: DIFF: 2010-11-07 01:12:33 EDT - 2010-11-08 19:59:59 EST = **P-0Y0M1DT19H47M26S**
|
||||
test_time_fall_type3_post_type3_redodt: DIFF: 2010-11-07 01:12:33 EDT - 2010-11-08 19:59:59 EST = **P-0Y0M1DT18H47M26S**
|
||||
test_time_fall_type3_post_type3_redost: DIFF: 2010-11-07 01:14:44 EST - 2010-11-08 19:59:59 EST = **P-0Y0M1DT18H45M15S**
|
||||
test_time_fall_type3_post_type3_st: DIFF: 2010-11-07 03:16:55 EST - 2010-11-08 19:59:59 EST = **P-0Y0M1DT16H43M4S**
|
||||
test_time_fall_type3_post_type3_post: DIFF: 2010-11-08 19:59:59 EST - 2010-11-08 18:57:55 EST = **P+0Y0M0DT1H2M4S**
|
||||
|
|
|
@ -54,7 +54,7 @@ echo 'bd8b ' . $end->format($date_format) . ' - ' . $start->format($date_format)
|
|||
echo "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
bd0 2010-11-07 01:00:00 EST America/New_York - 2010-11-07 01:59:59 EDT America/New_York = P0DT0H59M59S
|
||||
bd0 2010-11-07 01:00:00 EST America/New_York - 2010-11-07 01:59:59 EDT America/New_York = P0DT0H0M1S
|
||||
bd5 2010-11-07 01:30:00 EST America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT22H
|
||||
bd6 2010-11-07 01:30:00 EDT America/New_York - 2010-11-06 04:30:00 EDT America/New_York = P0DT21H
|
||||
bd8a 2010-11-07 01:00:00 EST America/New_York - 2010-11-06 01:00:00 EDT America/New_York = P1DT0H
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue