mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fixed bug #81458: Regression: Incorrect difference after timezone change
This commit is contained in:
parent
b1b6440d84
commit
904933e918
4
NEWS
4
NEWS
@ -7,6 +7,10 @@ PHP NEWS
|
||||
. Fixed bug #78647 (SEGFAULT in zend_do_perform_implementation_check).
|
||||
(Nikita)
|
||||
|
||||
- Date:
|
||||
. Fixed bug #81458 (Regression Incorrect difference after timezone change).
|
||||
(Derick)
|
||||
|
||||
- GD:
|
||||
. Fixed bug #71316 (libpng warning from imagecreatefromstring). (cmb)
|
||||
|
||||
|
@ -59,7 +59,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
|
||||
rt->s = two->s - one->s;
|
||||
rt->us = two->us - one->us;
|
||||
|
||||
rt->days = fabs(floor((one->sse - two->sse - (dst_h_corr * 3600) - (dst_m_corr * 60)) / 86400));
|
||||
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) {
|
||||
@ -147,6 +147,37 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
int timelib_diff_days(timelib_time *one, timelib_time *two)
|
||||
{
|
||||
int days = 0;
|
||||
|
||||
if (timelib_same_timezone(one, two)) {
|
||||
timelib_time *earliest, *latest;
|
||||
double earliest_time, latest_time;
|
||||
|
||||
if (timelib_time_compare(one, two) < 0) {
|
||||
earliest = one;
|
||||
latest = two;
|
||||
} else {
|
||||
earliest = two;
|
||||
latest = one;
|
||||
}
|
||||
timelib_hmsf_to_decimal_hour(earliest->h, earliest->i, earliest->s, earliest->us, &earliest_time);
|
||||
timelib_hmsf_to_decimal_hour(latest->h, latest->i, latest->s, latest->us, &latest_time);
|
||||
|
||||
days = llabs(timelib_epoch_days_from_time(one) - timelib_epoch_days_from_time(two));
|
||||
if (latest_time < earliest_time && days > 0) {
|
||||
days--;
|
||||
}
|
||||
} else {
|
||||
days = fabs(floor(one->sse - two->sse) / 86400);
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
|
||||
timelib_time *timelib_add(timelib_time *old_time, timelib_rel_time *interval)
|
||||
{
|
||||
int bias = 1;
|
||||
|
@ -930,3 +930,23 @@ timelib_sll timelib_get_current_offset(timelib_time *t)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int timelib_same_timezone(timelib_time *one, timelib_time *two)
|
||||
{
|
||||
if (one->zone_type != two->zone_type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ABBR || one->zone_type == TIMELIB_ZONETYPE_OFFSET) {
|
||||
if ((one->z + (one->dst * 3600)) == (two->z + (two->dst * 3600))) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (one->zone_type == TIMELIB_ZONETYPE_ID && strcmp(one->tz_info->name, two->tz_info->name) == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -207,6 +207,15 @@ void timelib_hms_to_decimal_hour(int hour, int min, int sec, double *h)
|
||||
}
|
||||
}
|
||||
|
||||
void timelib_hmsf_to_decimal_hour(int hour, int min, int sec, int us, double *h)
|
||||
{
|
||||
if (hour > 0) {
|
||||
*h = ((double)hour + (double)min / MINS_PER_HOUR + (double)sec / SECS_PER_HOUR) + (double)us / USECS_PER_HOUR;
|
||||
} else {
|
||||
*h = ((double)hour - (double)min / MINS_PER_HOUR - (double)sec / SECS_PER_HOUR) - (double)us / USECS_PER_HOUR;
|
||||
}
|
||||
}
|
||||
|
||||
timelib_sll timelib_hms_to_seconds(timelib_sll h, timelib_sll m, timelib_sll s)
|
||||
{
|
||||
return (h * SECS_PER_HOUR) + (m * 60) + s;
|
||||
|
@ -30,9 +30,9 @@
|
||||
# include "timelib_config.h"
|
||||
#endif
|
||||
|
||||
#define TIMELIB_VERSION 202108
|
||||
#define TIMELIB_EXTENDED_VERSION 20210801
|
||||
#define TIMELIB_ASCII_VERSION "2021.08"
|
||||
#define TIMELIB_VERSION 202110
|
||||
#define TIMELIB_EXTENDED_VERSION 20211001
|
||||
#define TIMELIB_ASCII_VERSION "2021.10"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
@ -799,6 +799,16 @@ timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *
|
||||
*/
|
||||
timelib_sll timelib_get_current_offset(timelib_time *t);
|
||||
|
||||
/**
|
||||
* Returns whether the timezone information in *one and *two are the same
|
||||
*
|
||||
* A timezone is considered the same if:
|
||||
* - the ->zone_type values are the same for *one and *two
|
||||
* - for TYPE_ABBR and TYPE_OFFSET, ->z + (->dst * 3600), is the same
|
||||
* - for TYPE_ID, the zone's names are the same
|
||||
*/
|
||||
int timelib_same_timezone(timelib_time *one, timelib_time *two);
|
||||
|
||||
/**
|
||||
* Displays debugging information about the time zone information in 'tz'.
|
||||
*/
|
||||
@ -961,6 +971,11 @@ void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec);
|
||||
*/
|
||||
void timelib_hms_to_decimal_hour(int hour, int min, int sec, double *h);
|
||||
|
||||
/**
|
||||
* Converts hour/min/sec/micro sec values into a decimal hour
|
||||
*/
|
||||
void timelib_hmsf_to_decimal_hour(int hour, int min, int sec, int us, double *h);
|
||||
|
||||
/**
|
||||
* Converts hour/min/sec values into seconds
|
||||
*/
|
||||
@ -1027,6 +1042,15 @@ int timelib_astro_rise_set_altitude(timelib_time *time, double lon, double lat,
|
||||
*/
|
||||
timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two);
|
||||
|
||||
/**
|
||||
* Calculates the difference in full days between two times
|
||||
*
|
||||
* The result is the number of full days between 'one' and 'two'. It does take
|
||||
* into account 23 and 25 hour (and variants) days when the zone_type
|
||||
* is TIMELIB_ZONETYPE_ID and have the same TZID for 'one' and 'two'.
|
||||
*/
|
||||
int timelib_diff_days(timelib_time *one, timelib_time *two);
|
||||
|
||||
/**
|
||||
* Adds the relative time information 'interval' to the base time 't'.
|
||||
*
|
||||
|
@ -84,9 +84,12 @@
|
||||
#define TIMELIB_TIME_PART_DONT_KEEP 0x00
|
||||
#define TIMELIB_TIME_PART_KEEP 0x01
|
||||
|
||||
#define MINS_PER_HOUR 60
|
||||
#define SECS_PER_ERA TIMELIB_LL_CONST(12622780800)
|
||||
#define SECS_PER_DAY 86400
|
||||
#define SECS_PER_HOUR 3600
|
||||
#define USECS_PER_HOUR TIMELIB_LL_CONST(3600000000)
|
||||
|
||||
#define DAYS_PER_WEEK 7
|
||||
#define DAYS_PER_YEAR 365
|
||||
#define DAYS_PER_LYEAR 366
|
||||
|
13
ext/date/tests/bug81458.phpt
Normal file
13
ext/date/tests/bug81458.phpt
Normal file
@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Test for bug #81458: Regression in PHP 8.1: Incorrect difference after timezone change
|
||||
--FILE--
|
||||
<?php
|
||||
$first = (new DateTime('2018-07-01 00:00:00.000000 America/Toronto'))->setTimezone(new DateTimeZone('UTC'));
|
||||
$second = new DateTime('2018-07-02 00:00:00.000000 America/Toronto');
|
||||
|
||||
var_dump($first->diff($second)->days);
|
||||
var_dump($first->diff($second)->d);
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
int(1)
|
Loading…
Reference in New Issue
Block a user