Skip to content

Commit 66ea59e

Browse files
committed
Import timelib 2021.07
Fixes: - Bug #80998 (Missing second with inverted interval). (Derick) - Bug #81106 (Regression in 8.1: add() now truncate ->f). (Derick)
1 parent 94bc5fc commit 66ea59e

File tree

6 files changed

+62
-16
lines changed

6 files changed

+62
-16
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ PHP NEWS
66
. Fixed bug #79580 (date_create_from_format misses leap year). (Derick)
77
. Fixed bug #80974 (Wrong diff between 2 dates in different timezones).
88
(Derick)
9+
. Fixed bug #80998 (Missing second with inverted interval). (Derick)
910
. Fixed bug #81097 (DateTimeZone silently falls back to UTC when providing an
1011
offset with seconds). (Derick)
12+
. Fixed bug #81106 (Regression in 8.1: add() now truncate ->f). (Derick)
1113
. Fixed bug #81273 (Date interval calculation not correct). (Derick)
1214

1315

ext/date/lib/interval.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,19 @@ timelib_time *timelib_sub(timelib_time *old_time, timelib_rel_time *interval)
207207
return t;
208208
}
209209

210+
static void do_range_limit(timelib_sll start, timelib_sll end, timelib_sll adj, timelib_sll *a, timelib_sll *b)
211+
{
212+
if (*a < start) {
213+
*b -= (start - *a - 1) / adj + 1;
214+
*a += adj * ((start - *a - 1) / adj + 1);
215+
}
216+
if (*a >= end) {
217+
*b += *a / adj;
218+
*a -= adj * (*a / adj);
219+
}
220+
}
221+
222+
210223
timelib_time *timelib_add_wall(timelib_time *old_time, timelib_rel_time *interval)
211224
{
212225
int bias = 1;
@@ -232,6 +245,7 @@ timelib_time *timelib_add_wall(timelib_time *old_time, timelib_rel_time *interva
232245
timelib_update_ts(t, NULL);
233246
}
234247

248+
do_range_limit(0, 1000000, 1000000, &interval->us, &interval->s);
235249
t->sse += bias * timelib_hms_to_seconds(interval->h, interval->i, interval->s);
236250
t->us += interval->us * bias;
237251
timelib_do_normalize(t);
@@ -271,6 +285,7 @@ timelib_time *timelib_sub_wall(timelib_time *old_time, timelib_rel_time *interva
271285
timelib_update_ts(t, NULL);
272286
}
273287

288+
do_range_limit(0, 1000000, 1000000, &interval->us, &interval->s);
274289
t->sse -= bias * timelib_hms_to_seconds(interval->h, interval->i, interval->s);
275290
t->us -= interval->us * bias;
276291
timelib_do_normalize(t);

ext/date/lib/parse_posix.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -405,12 +405,6 @@ timelib_posix_str* timelib_parse_posix_str(const char *posix)
405405
return tmp;
406406
}
407407

408-
typedef struct _posix_transitions {
409-
size_t count;
410-
timelib_sll times[6];
411-
timelib_sll types[6];
412-
} posix_transitions;
413-
414408
static const int month_lengths[2][MONTHS_PER_YEAR] = {
415409
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, // normal year
416410
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } // leap year
@@ -503,7 +497,7 @@ timelib_sll timelib_ts_at_start_of_year(timelib_sll year)
503497
);
504498
}
505499

506-
static void calc_transitions_for_year(timelib_tzinfo *tz, timelib_sll year, posix_transitions *transitions)
500+
void timelib_get_transitions_for_year(timelib_tzinfo *tz, timelib_sll year, timelib_posix_transitions *transitions)
507501
{
508502
timelib_sll trans_begin; /* Since start of the year */
509503
timelib_sll trans_end;
@@ -536,9 +530,9 @@ static void calc_transitions_for_year(timelib_tzinfo *tz, timelib_sll year, posi
536530

537531
ttinfo* timelib_fetch_posix_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
538532
{
539-
timelib_sll year;
540-
timelib_time dummy;
541-
posix_transitions transitions = { 0 };
533+
timelib_sll year;
534+
timelib_time dummy;
535+
timelib_posix_transitions transitions = { 0 };
542536
size_t i;
543537

544538
/* If there is no second (dst_end) information, the UTC offset is valid for the whole year, so no need to
@@ -555,9 +549,9 @@ ttinfo* timelib_fetch_posix_timezone_offset(timelib_tzinfo *tz, timelib_sll ts,
555549
year = dummy.y;
556550

557551
/* Calculate transition times for 'year-1', 'year', and 'year+1' */
558-
calc_transitions_for_year(tz, year - 1, &transitions);
559-
calc_transitions_for_year(tz, year, &transitions);
560-
calc_transitions_for_year(tz, year + 1, &transitions);
552+
timelib_get_transitions_for_year(tz, year - 1, &transitions);
553+
timelib_get_transitions_for_year(tz, year, &transitions);
554+
timelib_get_transitions_for_year(tz, year + 1, &transitions);
561555

562556
/* Check where the 'ts' falls in the 4 transitions */
563557
for (i = 1; i < transitions.count; i++) {

ext/date/lib/timelib.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@
3030
# include "timelib_config.h"
3131
#endif
3232

33-
#define TIMELIB_VERSION 202106
34-
#define TIMELIB_EXTENDED_VERSION 20210601
35-
#define TIMELIB_ASCII_VERSION "2021.06"
33+
#define TIMELIB_VERSION 202107
34+
#define TIMELIB_EXTENDED_VERSION 20210701
35+
#define TIMELIB_ASCII_VERSION "2021.07"
3636

3737
#include <stdlib.h>
3838
#include <stdbool.h>
@@ -180,6 +180,12 @@ typedef struct _timelib_posix_str
180180
int type_index_dst_type; // index into tz->type
181181
} timelib_posix_str;
182182

183+
typedef struct _timelib_posix_transitions {
184+
size_t count;
185+
timelib_sll times[6];
186+
timelib_sll types[6];
187+
} timelib_posix_transitions;
188+
183189
typedef struct _timelib_tzinfo
184190
{
185191
char *name;
@@ -1046,6 +1052,12 @@ void timelib_posix_str_dtor(timelib_posix_str *ps);
10461052

10471053
timelib_posix_str* timelib_parse_posix_str(const char *posix);
10481054

1055+
/**
1056+
* Calculate the two yearly to/from DST
1057+
*/
1058+
void timelib_get_transitions_for_year(timelib_tzinfo *tz, timelib_sll year, timelib_posix_transitions *transitions);
1059+
1060+
10491061
#ifdef __cplusplus
10501062
} /* extern "C" */
10511063
#endif

ext/date/tests/bug80998.phpt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #80998: Missing second with inverted interval
3+
--FILE--
4+
<?php
5+
$date = new DateTime('2021-04-05 14:00:00');
6+
$interval = new DateInterval('P0DT10799S');
7+
$interval->f = 0.999999;
8+
$interval->invert = 1;
9+
$date->add($interval);
10+
$string = $date->format('Y-m-d H:i:s.u');
11+
?>
12+
--EXPECT--

ext/date/tests/bug81106.phpt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--TEST--
2+
Bug #81106: Regression in 8.1: add() now truncate ->f
3+
--FILE--
4+
<?php
5+
$dateInterval = new DateInterval('PT0S');
6+
$dateInterval->f = 1.234;
7+
8+
echo (new DateTimeImmutable('2000-01-01 00:00:00'))->add($dateInterval)->format('Y-m-d H:i:s.u');
9+
?>
10+
--EXPECT--
11+
2000-01-01 00:00:01.234000

0 commit comments

Comments
 (0)