Merge remote-tracking branch 'derickr/fix-datetime-diff-around-dst-transition' into PHP-8.2

This commit is contained in:
Derick Rethans 2023-04-18 13:47:00 +01:00
commit d1af263dd9
4 changed files with 40 additions and 93 deletions

View file

@ -36,25 +36,6 @@ static void swap_times(timelib_time **one, timelib_time **two, timelib_rel_time
rt->invert = 1; 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) 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 /* 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); rt->days = timelib_diff_days(one, two);
/* Fall Back: Cater for transition period, where rt->invert is 0, but there are negative numbers */ /* Fall Back: Cater for transition period, where rt->invert is 0, but there are negative numbers */
if (one->dst == 1 && two->dst == 0) { if (two->sse < one->sse) {
/* First for two "Type 3" times */ timelib_sll flipped = llabs((rt->i * 60) + (rt->s) - dst_corr);
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID) { rt->h = flipped / SECS_PER_HOUR;
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL); rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
if ( rt->s = flipped % 60;
success &&
one->sse < trans_transition_time && rt->invert = 1 - rt->invert;
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++;
}
} }
timelib_do_rel_normalize(rt->invert ? one : two, rt); timelib_do_rel_normalize(rt->invert ? one : two, rt);
/* Do corrections for "Type 3" times with the same TZID */ if (one->dst == 1 && two->dst == 0) { /* Fall Back */
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID && strcmp(one->tz_info->name, two->tz_info->name) == 0) { if (two->tz_info) {
if (one->dst == 1 && two->dst == 0) { /* Fall Back */ if ((two->sse - one->sse + dst_corr) < SECS_PER_DAY) {
if (two->tz_info) { rt->h -= dst_h_corr;
int success = timelib_get_time_zone_offset_info(two->sse, two->tz_info, &trans_offset, &trans_transition_time, NULL); rt->i -= dst_m_corr;
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;
}
} }
} }
} else { } else if (one->dst == 0 && two->dst == 1) { /* Spring Forward */
rt->h -= dst_h_corr; if (two->tz_info) {
rt->i -= dst_m_corr; 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; return rt;

View file

@ -30,9 +30,9 @@
# include "timelib_config.h" # include "timelib_config.h"
#endif #endif
#define TIMELIB_VERSION 202205 #define TIMELIB_VERSION 202206
#define TIMELIB_EXTENDED_VERSION 20220501 #define TIMELIB_EXTENDED_VERSION 20220601
#define TIMELIB_ASCII_VERSION "2022.05" #define TIMELIB_ASCII_VERSION "2022.06"
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>

View file

@ -2,8 +2,6 @@
DateTime::diff() -- fall type3 type3 DateTime::diff() -- fall type3 type3
--CREDITS-- --CREDITS--
Daniel Convissor <danielc@php.net> Daniel Convissor <danielc@php.net>
--XFAIL--
Various bugs exist
--FILE-- --FILE--
<?php <?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_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_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_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_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_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** 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_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_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_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_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_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** test_time_fall_type3_post_type3_post: DIFF: 2010-11-08 19:59:59 EST - 2010-11-08 18:57:55 EST = **P+0Y0M0DT1H2M4S**

View file

@ -54,7 +54,7 @@ echo 'bd8b ' . $end->format($date_format) . ' - ' . $start->format($date_format)
echo "\n"; echo "\n";
?> ?>
--EXPECT-- --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 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 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 bd8a 2010-11-07 01:00:00 EST America/New_York - 2010-11-06 01:00:00 EDT America/New_York = P1DT0H