Skip to content

Commit cd6c338

Browse files
committed
Merge branch 'PHP-8.1'
2 parents c7875a6 + e6c4988 commit cd6c338

File tree

2 files changed

+96
-20
lines changed

2 files changed

+96
-20
lines changed

ext/date/php_date.c

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,6 +3631,15 @@ PHP_FUNCTION(timezone_transitions_get)
36313631
add_assoc_string(&element, "abbr", &tzobj->tzi.tz->timezone_abbr[tzobj->tzi.tz->type[i].abbr_idx]); \
36323632
add_next_index_zval(return_value, &element);
36333633

3634+
#define add_from_tto(to,ts) \
3635+
array_init(&element); \
3636+
add_assoc_long(&element, "ts", ts); \
3637+
add_assoc_str(&element, "time", php_format_date(DATE_FORMAT_ISO8601, 13, ts, 0)); \
3638+
add_assoc_long(&element, "offset", (to)->offset); \
3639+
add_assoc_bool(&element, "isdst", (to)->is_dst); \
3640+
add_assoc_string(&element, "abbr", (to)->abbr); \
3641+
add_next_index_zval(return_value, &element);
3642+
36343643
#define add_last() add(tzobj->tzi.tz->bit64.timecnt - 1, timestamp_begin)
36353644

36363645
array_init(return_value);
@@ -3660,7 +3669,13 @@ PHP_FUNCTION(timezone_transitions_get)
36603669

36613670
if (!found) {
36623671
if (tzobj->tzi.tz->bit64.timecnt > 0) {
3663-
add_last();
3672+
if (tzobj->tzi.tz->posix_info && tzobj->tzi.tz->posix_info->dst_end) {
3673+
timelib_time_offset *tto = timelib_get_time_zone_info(timestamp_begin, tzobj->tzi.tz);
3674+
add_from_tto(tto, timestamp_begin);
3675+
timelib_time_offset_dtor(tto);
3676+
} else {
3677+
add_last();
3678+
}
36643679
} else {
36653680
add_nominal();
36663681
}
@@ -3673,31 +3688,34 @@ PHP_FUNCTION(timezone_transitions_get)
36733688
return;
36743689
}
36753690
}
3676-
if (tzobj->tzi.tz->posix_info && tzobj->tzi.tz->posix_info->dst_end) {
3677-
int i, j;
3678-
timelib_sll start_y, end_y, dummy_m, dummy_d;
3679-
timelib_sll last_transition_ts = tzobj->tzi.tz->trans[tzobj->tzi.tz->bit64.timecnt - 1];
3691+
}
3692+
if (tzobj->tzi.tz->posix_info && tzobj->tzi.tz->posix_info->dst_end) {
3693+
int i, j;
3694+
timelib_sll start_y, end_y, dummy_m, dummy_d;
3695+
timelib_sll last_transition_ts = tzobj->tzi.tz->trans[tzobj->tzi.tz->bit64.timecnt - 1];
36803696

3681-
/* Find out year for last transition */
3682-
timelib_unixtime2date(last_transition_ts, &start_y, &dummy_m, &dummy_d);
3697+
/* Find out year for last transition */
3698+
timelib_unixtime2date(last_transition_ts, &start_y, &dummy_m, &dummy_d);
36833699

3684-
/* Find out year for final boundary timestamp */
3685-
timelib_unixtime2date(timestamp_end, &end_y, &dummy_m, &dummy_d);
3700+
/* Find out year for final boundary timestamp */
3701+
timelib_unixtime2date(timestamp_end, &end_y, &dummy_m, &dummy_d);
36863702

3687-
for (i = start_y; i <= end_y; i++) {
3688-
timelib_posix_transitions transitions = { 0 };
3703+
for (i = start_y; i <= end_y; i++) {
3704+
timelib_posix_transitions transitions = { 0 };
36893705

3690-
timelib_get_transitions_for_year(tzobj->tzi.tz, i, &transitions);
3706+
timelib_get_transitions_for_year(tzobj->tzi.tz, i, &transitions);
36913707

3692-
for (j = 0; j < transitions.count; j++) {
3693-
if (transitions.times[j] <= last_transition_ts) {
3694-
continue;
3695-
}
3696-
if (transitions.times[j] > timestamp_end) {
3697-
return;
3698-
}
3699-
add_by_index(transitions.types[j], transitions.times[j]);
3708+
for (j = 0; j < transitions.count; j++) {
3709+
if (transitions.times[j] <= last_transition_ts) {
3710+
continue;
3711+
}
3712+
if (transitions.times[j] < timestamp_begin) {
3713+
continue;
3714+
}
3715+
if (transitions.times[j] > timestamp_end) {
3716+
return;
37003717
}
3718+
add_by_index(transitions.types[j], transitions.times[j]);
37013719
}
37023720
}
37033721
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
GH-7752: DateTimeZone::getTransitions() does not return enough information
3+
--FILE--
4+
<?php
5+
function showTransitions(string $tzid, int $from)
6+
{
7+
$to = $from + ((2.5 * 366) * 24 * 60 * 60);
8+
9+
echo "{$tzid} from @{$from}-@{$to}:\n\n";
10+
11+
$tz = new DateTimeZone($tzid);
12+
foreach ($tz->getTransitions($from, $to) as $t) {
13+
printf("%12d %s %6d %s %s\n", $t['ts'], $t['time'], $t['offset'], $t['isdst'] ? "DST" : " x ", $t['abbr']);
14+
}
15+
echo "\n";
16+
}
17+
18+
19+
showTransitions('Europe/London', 1648342200);
20+
showTransitions('America/Los_Angeles', 1648557596); // GH Issue 7752
21+
showTransitions('America/Chicago', 1293861600); // PHP Bug 81660
22+
showTransitions('Europe/Paris', 1645095600); // GH Issue 8108
23+
?>
24+
--EXPECT--
25+
Europe/London from @1648342200-@1727398200:
26+
27+
1648342200 2022-03-27T00:50:00+0000 0 x GMT
28+
1648342800 2022-03-27T01:00:00+0000 3600 DST BST
29+
1667091600 2022-10-30T01:00:00+0000 0 x GMT
30+
1679792400 2023-03-26T01:00:00+0000 3600 DST BST
31+
1698541200 2023-10-29T01:00:00+0000 0 x GMT
32+
1711846800 2024-03-31T01:00:00+0000 3600 DST BST
33+
34+
America/Los_Angeles from @1648557596-@1727613596:
35+
36+
1648557596 2022-03-29T12:39:56+0000 -25200 DST PDT
37+
1667725200 2022-11-06T09:00:00+0000 -28800 x PST
38+
1678615200 2023-03-12T10:00:00+0000 -25200 DST PDT
39+
1699174800 2023-11-05T09:00:00+0000 -28800 x PST
40+
1710064800 2024-03-10T10:00:00+0000 -25200 DST PDT
41+
42+
America/Chicago from @1293861600-@1372917600:
43+
44+
1293861600 2011-01-01T06:00:00+0000 -21600 x CST
45+
1300003200 2011-03-13T08:00:00+0000 -18000 DST CDT
46+
1320562800 2011-11-06T07:00:00+0000 -21600 x CST
47+
1331452800 2012-03-11T08:00:00+0000 -18000 DST CDT
48+
1352012400 2012-11-04T07:00:00+0000 -21600 x CST
49+
1362902400 2013-03-10T08:00:00+0000 -18000 DST CDT
50+
51+
Europe/Paris from @1645095600-@1724151600:
52+
53+
1645095600 2022-02-17T11:00:00+0000 3600 x CET
54+
1648342800 2022-03-27T01:00:00+0000 7200 DST CEST
55+
1667091600 2022-10-30T01:00:00+0000 3600 x CET
56+
1679792400 2023-03-26T01:00:00+0000 7200 DST CEST
57+
1698541200 2023-10-29T01:00:00+0000 3600 x CET
58+
1711846800 2024-03-31T01:00:00+0000 7200 DST CEST

0 commit comments

Comments
 (0)