* Fix next_day_start from miscalculating daylight saving dates

* Add failsafe for do-while loop in next_week_start

* Add changelog

* Add seconds to setTime
This commit is contained in:
Ilyas Foo 2021-10-11 09:45:24 +08:00 committed by GitHub
parent 76c082ff2c
commit 364b284e3e
3 changed files with 49 additions and 13 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: Fix
Fix analytics crashing on daylight saving #7763

View File

@ -302,24 +302,18 @@ class TimeInterval {
* @return DateTime
*/
public static function next_day_start( $datetime, $reversed = false ) {
$seconds_into_day = (int) $datetime->format( 'H' ) * HOUR_IN_SECONDS + (int) $datetime->format( 'i' ) * MINUTE_IN_SECONDS + (int) $datetime->format( 's' );
$oneday = new \DateInterval( 'P1D' );
$new_datetime = clone $datetime;
// The day boundary is actually next midnight when going in reverse, so set it to day -1 at 23:59:59.
if ( $reversed ) {
$timestamp = (int) $datetime->format( 'U' );
$next_day_timestamp = $timestamp - ( $seconds_into_day + 1 );
$new_datetime->sub( $oneday );
$new_datetime->setTime( 23, 59, 59 );
} else {
$day_increment = new \DateInterval( 'P1D' ); // Plus 1 Day.
$next_datetime = clone $datetime;
$next_datetime->add( $day_increment );
$timestamp = (int) $next_datetime->format( 'U' );
$next_day_timestamp = $timestamp - $seconds_into_day;
$new_datetime->add( $oneday );
$new_datetime->setTime( 0, 0, 0 );
}
$next_day = new \DateTime();
$next_day->setTimestamp( $next_day_timestamp );
$next_day->setTimezone( new \DateTimeZone( wc_timezone_string() ) );
return $next_day;
return $new_datetime;
}
/**
@ -332,8 +326,12 @@ class TimeInterval {
public static function next_week_start( $datetime, $reversed = false ) {
$first_day_of_week = absint( get_option( 'start_of_week' ) );
$initial_week_no = self::week_number( $datetime, $first_day_of_week );
$failsafe_count = 0;
do {
if ( $failsafe_count++ >= 7 ) {
break;
}
$datetime = self::next_day_start( $datetime, $reversed );
$current_week_no = self::week_number( $datetime, $first_day_of_week );
} while ( $current_week_no === $initial_week_no );

View File

@ -670,6 +670,40 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case {
}
}
/**
* Test function that returns beginning of next day with daylight saving. Auckland's 2021 daylight saving
* starts on 26th September 2021 at 02:00:00 and ends on 3rd April 2022 at 03:00:00.
*/
public function test_next_day_start_daylight_saving() {
update_option( 'timezone_string', 'Pacific/Auckland' );
$settings = array(
'2021-09-26T00:00:00' => array( // Before daylight saving starts.
0 => '2021-09-27T00:00:00',
1 => '2021-09-25T23:59:59',
),
'2021-09-26T03:00:00' => array( // After daylight saving starts.
0 => '2021-09-27T00:00:00',
1 => '2021-09-25T23:59:59',
),
'2022-04-03T00:00:00' => array( // Before daylight saving ends.
0 => '2022-04-04T00:00:00',
1 => '2022-04-02T23:59:59',
),
'2022-04-03T23:59:00' => array( // After daylight saving ends.
0 => '2022-04-04T00:00:00',
1 => '2022-04-02T23:59:59',
),
);
foreach ( $settings as $datetime_s => $setting ) {
$datetime = new DateTime( $datetime_s, new DateTimeZone( 'Pacific/Auckland' ) );
foreach ( $setting as $reversed => $exp_value ) {
$result_dt = TimeInterval::next_day_start( $datetime, $reversed );
$this->assertEquals( $exp_value, $result_dt->format( TimeInterval::$iso_datetime_format ), __FUNCTION__ . ": DT: $datetime_s; R: $reversed" );
}
}
}
/**
* Test function that returns beginning of next week, for weeks starting on Monday.
*/