Make WordPress Core

Ticket #48384: 48384.2.diff

File 48384.2.diff, 5.3 KB (added by SergeyBiryukov, 6 years ago)
  • src/wp-includes/general-template.php

     
    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 the result. However, the values might get out of sync in database,
     2612 * typically because of timezone setting changes. The parameter ensures the 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 *                            Default 'date'.
     2620 * @param string      $source Optional. Local or UTC time to use from database. Accepts 'local' or 'gmt'.
     2621 *                            Default 'local'.
    26132622 * @return DateTimeImmutable|false Time object on success, false on failure.
    26142623 */
    2615 function get_post_datetime( $post = null, $field = 'date' ) {
     2624function get_post_datetime( $post = null, $field = 'date', $source = 'local' ) {
    26162625        $post = get_post( $post );
    26172626
    26182627        if ( ! $post ) {
     
    26192628                return false;
    26202629        }
    26212630
    2622         $time = ( 'modified' === $field ) ? $post->post_modified : $post->post_date;
     2631        $wp_timezone = wp_timezone();
    26232632
     2633        if ( 'gmt' === $source ) {
     2634                $time     = ( 'modified' === $field ) ? $post->post_modified_gmt : $post->post_date_gmt;
     2635                $timezone = new DateTimeZone( 'UTC' );
     2636        } else {
     2637                $time     = ( 'modified' === $field ) ? $post->post_modified : $post->post_date;
     2638                $timezone = $wp_timezone;
     2639        }
     2640
    26242641        if ( empty( $time ) || '0000-00-00 00:00:00' === $time ) {
    26252642                return false;
    26262643        }
    26272644
    2628         return date_create_immutable_from_format( 'Y-m-d H:i:s', $time, wp_timezone() );
     2645        $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', $time, $timezone );
     2646
     2647        if ( false === $datetime ) {
     2648                return false;
     2649        }
     2650
     2651        return $datetime->setTimezone( $wp_timezone );
    26292652}
    26302653
    26312654/**
     
    26372660 * @since 5.3.0
    26382661 *
    26392662 * @param int|WP_Post $post  Optional. WP_Post object or ID. Default is global `$post` object.
    2640  * @param string      $field Optional. Post field to use. Accepts 'date' or 'modified'.
     2663 * @param string      $field Optional. Published or modified time to use from database. Accepts 'date' or 'modified'.
     2664 *                           Default 'date'.
    26412665 * @return int|false Unix timestamp on success, false on failure.
    26422666 */
    26432667function get_post_timestamp( $post = null, $field = 'date' ) {
     
    27292753                return false;
    27302754        }
    27312755
    2732         $datetime = get_post_datetime( $post, 'modified' );
     2756        $source   = ( $gmt ) ? 'gmt' : 'local';
     2757        $datetime = get_post_datetime( $post, 'modified', $source );
    27332758
    27342759        if ( false === $datetime ) {
    27352760                return false;
  • tests/phpunit/tests/date/postTime.php

     
    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_with_gmt_offset() {
     70                // Set the timezone to UTC+0.
     71                update_option( 'gmt_offset', 0 );
     72
     73                $datetime = new DateTimeImmutable( 'now', new DateTimeZone( 'UTC' ) );
     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                // Change the timezone to UTC+2.
     84                update_option( 'gmt_offset', 2 );
     85
     86                $this->assertEquals( $rfc3339, get_post_time( DATE_RFC3339, true, $post_id ) );
     87                $this->assertEquals( $rfc3339, get_post_modified_time( DATE_RFC3339, true, $post_id ) );
     88        }
     89
     90        /**
     91         * @ticket 48384
     92         */
     93        public function test_should_keep_utc_time_on_timezone_change() {
     94                $timezone = 'UTC';
     95                update_option( 'timezone_string', $timezone );
     96
     97                $datetime = new DateTimeImmutable( 'now', new DateTimeZone( $timezone ) );
     98                $mysql    = $datetime->format( 'Y-m-d H:i:s' );
     99                $rfc3339  = $datetime->format( DATE_RFC3339 );
     100                $post_id  = self::factory()->post->create(
     101                        array(
     102                                'post_date'     => $mysql,
     103                                'post_modified' => $mysql,
     104                        )
     105                );
     106
     107                update_option( 'timezone_string', 'Europe/Kiev' );
     108
     109                $this->assertEquals( $rfc3339, get_post_time( DATE_RFC3339, true, $post_id ) );
     110                $this->assertEquals( $rfc3339, get_post_modified_time( DATE_RFC3339, true, $post_id ) );
     111        }
    65112}