Make WordPress Core

Changeset 45901


Ignore:
Timestamp:
08/28/2019 12:51:16 AM (5 years ago)
Author:
SergeyBiryukov
Message:

Date/Time: Introduce wp_date() to retrieve the date in localized format.

Convert date_i18n() into a wrapper for wp_date().

wp_date() is intended as a replacement for date_i18n() without legacy quirks in it. It accepts a true Unix timestamp (not summed with timezone offset) and an arbitrary timezone.

Props Rarst, mboynes, MikeHansenMe, rmccue, nacin.
Fixes #28636.

Location:
trunk/src/wp-includes
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/default-filters.php

    r45507 r45901  
    209209add_filter( 'widget_text_content', 'shortcode_unautop' );
    210210add_filter( 'widget_text_content', 'do_shortcode', 11 ); // Runs after wpautop(); note that $post global will be null when shortcodes run.
    211 
    212 add_filter( 'date_i18n', 'wp_maybe_decline_date' );
    213211
    214212// RSS filters
  • trunk/src/wp-includes/functions.php

    r45898 r45901  
    9292
    9393/**
    94  * Retrieves the timezone from current settings as a string.
     94 * Retrieves the timezone from site settings as a string.
    9595 *
    9696 * Uses the `timezone_string` option to get a proper timezone if available,
     
    121121
    122122/**
    123  * Retrieves the timezone from current settings as a `DateTimeZone` object.
     123 * Retrieves the timezone from site settings as a `DateTimeZone` object.
    124124 *
    125125 * Timezone can be based on a PHP timezone string or a ±HH:MM offset.
     
    147147 *
    148148 * @since 0.71
     149 * @since 5.3.0 Converted into a wrapper for wp_date().
    149150 *
    150151 * @global WP_Locale $wp_locale WordPress date and time locale object.
    151152 *
    152  * @param string   $dateformatstring      Format to display the date.
     153 * @param string   $format                Format to display the date.
    153154 * @param int|bool $timestamp_with_offset Optional. A sum of Unix timestamp and timezone offset in seconds.
    154155 *                                        Default false.
    155156 * @param bool     $gmt                   Optional. Whether to use GMT timezone. Only applies if timestamp is
    156157 *                                        not provided. Default false.
    157  *
    158158 * @return string The date, translated if locale specifies it.
    159159 */
    160 function date_i18n( $dateformatstring, $timestamp_with_offset = false, $gmt = false ) {
    161     global $wp_locale;
    162 
    163     $i = $timestamp_with_offset;
    164 
    165     if ( ! is_numeric( $i ) ) {
    166         $i = current_time( 'timestamp', $gmt );
    167     }
    168 
    169     /*
    170      * Store original value for language with untypical grammars.
    171      * See https://core.trac.wordpress.org/ticket/9396
    172      */
    173     $req_format = $dateformatstring;
    174     $new_format = '';
    175 
    176     // We need to unpack shorthand `r` format because it has parts that might be localized.
    177     $dateformatstring = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $dateformatstring );
    178 
    179     /*
    180      * Timestamp with offset is typically produced by a UTC `strtotime()` call on an input without timezone.
    181      * This is the best attempt to reverse that operation into a local time to use.
    182      */
    183     $local_time = gmdate( 'Y-m-d H:i:s', $i );
    184     $gmt_mode   = $gmt && ( false === $timestamp_with_offset );
    185     $timezone   = $gmt_mode ? new DateTimeZone( 'UTC' ) : wp_timezone();
    186     $datetime   = date_create( $local_time, $timezone );
     160function date_i18n( $format, $timestamp_with_offset = false, $gmt = false ) {
     161    // If timestamp is omitted it should be current time (summed with offset, unless `$gmt` is true).
     162    $timestamp = $timestamp_with_offset ? $timestamp_with_offset : current_time( 'timestamp', $gmt );
    187163
    188164    /*
     
    190166     * Ideally this function should never be used to produce a timestamp.
    191167     */
    192     $timestamp_mode = ( 'U' === $dateformatstring );
    193 
    194     if ( $timestamp_mode ) {
    195         $new_format = $i;
    196     }
    197 
    198     if ( ! $timestamp_mode && ! empty( $wp_locale->month ) && ! empty( $wp_locale->weekday ) ) {
    199         $month   = $wp_locale->get_month( $datetime->format( 'm' ) );
    200         $weekday = $wp_locale->get_weekday( $datetime->format( 'w' ) );
    201 
    202         $format_length = strlen( $dateformatstring );
     168    if ( 'U' === $format ) {
     169        $date = $timestamp;
     170    } elseif ( $gmt && ! $timestamp_with_offset ) { // Current time in UTC.
     171        $date = wp_date( $format, null, new DateTimeZone( 'UTC' ) );
     172    } elseif ( ! $timestamp_with_offset ) { // Current time in site's timezone.
     173        $date = wp_date( $format );
     174    } else {
     175        /*
     176         * Timestamp with offset is typically produced by a UTC `strtotime()` call on an input without timezone.
     177         * This is the best attempt to reverse that operation into a local time to use.
     178         */
     179        $local_time = gmdate( 'Y-m-d H:i:s', $timestamp );
     180        $timezone   = wp_timezone();
     181        $datetime   = date_create( $local_time, $timezone );
     182        $date       = wp_date( $format, $datetime->getTimestamp(), $timezone );
     183    }
     184
     185    /**
     186     * Filters the date formatted based on the locale.
     187     *
     188     * @since 2.8.0
     189     *
     190     * @param string $date      Formatted date string.
     191     * @param string $format    Format to display the date.
     192     * @param int    $timestamp A sum of Unix timestamp and timezone offset in seconds.
     193     *                          Might be without offset if input omitted timestamp but requested GMT.
     194     * @param bool   $gmt       Whether to use GMT timezone. Only applies if timestamp was not provided.
     195     *                          Default false.
     196     */
     197    $date = apply_filters( 'date_i18n', $date, $format, $timestamp, $gmt );
     198
     199    return $date;
     200}
     201
     202/**
     203 * Retrieves the date, in localized format.
     204 *
     205 * This is a newer function, intended to replace `date_i18n()` without legacy quirks in it.
     206 *
     207 * Note that, unlike `date_i18n()`, this function accepts a true Unix timestamp, not summed with timezone offset.
     208 *
     209 * @since 5.3.0
     210 *
     211 * @param string       $format    PHP date format.
     212 * @param int          $timestamp Optional. Unix timestamp. Defaults to current time.
     213 * @param DateTimeZone $timezone  Optional. Timezone to output result in. Defaults to timezone from site settings.
     214 *
     215 * @return string The date, translated if locale specifies it.
     216 */
     217function wp_date( $format, $timestamp = null, $timezone = null ) {
     218    global $wp_locale;
     219
     220    if ( ! $timestamp ) {
     221        $timestamp = time();
     222    }
     223
     224    if ( ! $timezone ) {
     225        $timezone = wp_timezone();
     226    }
     227
     228    $datetime = date_create( '@' . $timestamp );
     229    $datetime->setTimezone( $timezone );
     230
     231    if ( empty( $wp_locale->month ) || empty( $wp_locale->weekday ) ) {
     232        $date = $datetime->format( $format );
     233    } else {
     234        // We need to unpack shorthand `r` format because it has parts that might be localized.
     235        $format = preg_replace( '/(?<!\\\\)r/', DATE_RFC2822, $format );
     236
     237        $new_format    = '';
     238        $format_length = strlen( $format );
     239        $month         = $wp_locale->get_month( $datetime->format( 'm' ) );
     240        $weekday       = $wp_locale->get_weekday( $datetime->format( 'w' ) );
    203241
    204242        for ( $i = 0; $i < $format_length; $i ++ ) {
    205             switch ( $dateformatstring[ $i ] ) {
     243            switch ( $format[ $i ] ) {
    206244                case 'D':
    207245                    $new_format .= backslashit( $wp_locale->get_weekday_abbrev( $weekday ) );
     
    223261                    break;
    224262                case '\\':
    225                     $new_format .= $dateformatstring[ $i ];
     263                    $new_format .= $format[ $i ];
    226264
    227265                    // If character follows a slash, we add it without translating.
    228266                    if ( $i < $format_length ) {
    229                         $new_format .= $dateformatstring[ ++$i ];
     267                        $new_format .= $format[ ++$i ];
    230268                    }
    231269                    break;
    232270                default:
    233                     $new_format .= $dateformatstring[ $i ];
     271                    $new_format .= $format[ $i ];
    234272                    break;
    235273            }
    236274        }
    237     }
    238 
    239     $j = $datetime->format( $new_format );
     275
     276        $date = $datetime->format( $new_format );
     277        $date = wp_maybe_decline_date( $date );
     278    }
    240279
    241280    /**
    242281     * Filters the date formatted based on the locale.
    243282     *
    244      * @since 2.8.0
    245      *
    246      * @param string $j          Formatted date string.
    247      * @param string $req_format Format to display the date.
    248      * @param int    $i          A sum of Unix timestamp and timezone offset in seconds.
    249      * @param bool   $gmt        Whether to use GMT timezone. Only applies if timestamp was
    250      *                           not provided. Default false.
     283     * @since 5.3.0
     284     *
     285     * @param string       $date      Formatted date string.
     286     * @param string       $format    Format to display the date.
     287     * @param int          $timestamp Unix timestamp.
     288     * @param DateTimeZone $timezone  Timezone.
     289     *
    251290     */
    252     $j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
    253 
    254     return $j;
     291    $date = apply_filters( 'wp_date', $date, $format, $timestamp, $timezone );
     292
     293    return $date;
    255294}
    256295
Note: See TracChangeset for help on using the changeset viewer.