Make WordPress Core

Ticket #48384: 48384-fixed-utc-time-slipping-on-time-zone-change.patch

File 48384-fixed-utc-time-slipping-on-time-zone-change.patch, 4.1 KB (added by Rarst, 5 years ago)
  • tests/phpunit/tests/date/postTime.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    6262                $this->assertEquals( $rfc3339, get_post_modified_time( DATE_RFC3339, false, $post_id, true ) );
    6363                $this->assertEquals( $rfc3339_utc, get_post_modified_time( DATE_RFC3339, true, $post_id, true ) );
    6464        }
     65
     66        /**
     67         * @ticket 48384
     68         */
     69        public function test_should_keep_utc_time_on_timezone_change() {
     70
     71                $timezone = 'UTC';
     72                update_option( 'timezone_string', $timezone );
     73                $datetime = new DateTimeImmutable( 'now', new DateTimeZone( $timezone ) );
     74                $mysql    = $datetime->format( 'Y-m-d H:i:s' );
     75                $rfc3339  = $datetime->format( DATE_RFC3339 );
     76                $post_id  = self::factory()->post->create(
     77                        array(
     78                                'post_date'     => $mysql,
     79                                'post_modified' => $mysql,
     80                        )
     81                );
     82
     83                update_option( 'timezone_string', 'Europe/Kiev' );
     84
     85                $this->assertEquals( $rfc3339, get_post_time( DATE_RFC3339, true, $post_id ) );
     86                $this->assertEquals( $rfc3339, get_post_modified_time( DATE_RFC3339, true, $post_id ) );
     87        }
    6588}
  • src/wp-includes/general-template.php

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    25652565                return false;
    25662566        }
    25672567
    2568         $datetime = get_post_datetime( $post );
     2568        $source   = ( $gmt ) ? 'gmt' : 'local';
     2569        $datetime = get_post_datetime( $post, 'date', $source );
    25692570
    25702571        if ( false === $datetime ) {
    25712572                return false;
     
    26062607 *
    26072608 * The object will be set to the timezone from WordPress settings.
    26082609 *
     2610 * For legacy reasons this function allows to choose to instance from local or UTC time in database.
     2611 * Normally this should make no difference to result. However the values might get out of sync in database,
     2612 * typically because of time zone setting changed. The parameter ensures ability to reproduce backwards
     2613 * compatible behaviors in such cases.
     2614 *
    26092615 * @since 5.3.0
    26102616 *
    2611  * @param int|WP_Post $post  Optional. WP_Post object or ID. Default is global `$post` object.
    2612  * @param string      $field Optional. Post field to use. Accepts 'date' or 'modified'.
     2617 * @param int|WP_Post $post   Optional. WP_Post object or ID. Default is global `$post` object.
     2618 * @param string      $field  Optional. Published or modified time to use from database. Accepts 'date' or 'modified'.
     2619 * @param string      $source Optional. Local or UTC time to use from database. Accepts 'local' or 'gmt'.
     2620 *
    26132621 * @return DateTimeImmutable|false Time object on success, false on failure.
    26142622 */
    2615 function get_post_datetime( $post = null, $field = 'date' ) {
     2623function get_post_datetime( $post = null, $field = 'date', $source = 'local' ) {
    26162624        $post = get_post( $post );
    26172625
    26182626        if ( ! $post ) {
    26192627                return false;
    26202628        }
    26212629
    2622         $time = ( 'modified' === $field ) ? $post->post_modified : $post->post_date;
     2630        $wp_timezone = wp_timezone();
     2631
     2632        if ( 'gmt' === $source ) {
     2633                $time     = ( 'modified' === $field ) ? $post->post_modified_gmt : $post->post_date_gmt;
     2634                $timezone = new DateTimeZone( 'UTC' );
     2635        } else {
     2636                $time     = ( 'modified' === $field ) ? $post->post_modified : $post->post_date;
     2637                $timezone = $wp_timezone;
     2638        }
    26232639
    26242640        if ( empty( $time ) || '0000-00-00 00:00:00' === $time ) {
    26252641                return false;
    26262642        }
    26272643
    2628         return date_create_immutable_from_format( 'Y-m-d H:i:s', $time, wp_timezone() );
     2644        $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', $time, $timezone );
     2645
     2646        if ( false === $datetime ) {
     2647                return false;
     2648        }
     2649
     2650        return $datetime->setTimezone( $wp_timezone );
    26292651}
    26302652
    26312653/**
     
    27292751                return false;
    27302752        }
    27312753
    2732         $datetime = get_post_datetime( $post, 'modified' );
     2754        $source   = ( $gmt ) ? 'gmt' : 'local';
     2755        $datetime = get_post_datetime( $post, 'modified', $source );
    27332756
    27342757        if ( false === $datetime ) {
    27352758                return false;