WordPress.org

Make WordPress Core

Ticket #25768: functions.php.patch

File functions.php.patch, 7.4 KB (added by raubvogel, 6 years ago)
  • src/wp-includes/functions.php

     
    8282 * @return string The date, translated if locale specifies it.
    8383 */
    8484function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
     85        /* @var $wp_locale WP_Locale */
    8586        global $wp_locale;
    86         $i = $unixtimestamp;
     87        $timestamp = $unixtimestamp;
    8788
    88         if ( false === $i ) {
    89                 if ( ! $gmt )
    90                         $i = current_time( 'timestamp' );
     89        // get current timestamp if $unixtimestamp is false
     90        if ( false === $timestamp ) {
     91                if ( $gmt )
     92                        $timestamp = time();
    9193                else
    92                         $i = time();
    93                 // we should not let date() interfere with our
    94                 // specially computed timestamp
    95                 $gmt = true;
     94                        $timestamp = current_time( 'timestamp' );
    9695        }
    9796
    9897        // store original value for language with untypical grammars
     
    9998        // see http://core.trac.wordpress.org/ticket/9396
    10099        $req_format = $dateformatstring;
    101100
    102         $datefunc = $gmt? 'gmdate' : 'date';
     101        // get components of the date (timestamp) as array
     102        $datecomponents = getdate( $timestamp );
    103103
    104         if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
    105                 $datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
    106                 $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
    107                 $dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
    108                 $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
    109                 $datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
    110                 $datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
    111                 $dateformatstring = ' '.$dateformatstring;
    112                 $dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
    113                 $dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
    114                 $dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
    115                 $dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
    116                 $dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
    117                 $dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
     104        // numeric representation of a month, with leading zeros
     105        $datemonth = $wp_locale->get_month( $datecomponents['mon'] );
     106        $datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
     107        // numeric representation of the day of the week
     108        $dateweekday = $wp_locale->get_weekday( $datecomponents['wday'] );
     109        $dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
     110        // get if hour is Ante meridiem or Post meridiem
     111        $meridiem = $datecomponents['hours'] >= 12 ? 'pm' : 'am';
     112        // lowercase Ante meridiem and Post meridiem hours
     113        $datemeridiem = $wp_locale->get_meridiem( $meridiem );
     114        // uppercase Ante meridiem and Post meridiem
     115        $datemeridiem_capital = $wp_locale->get_meridiem( strtoupper( $meridiem ) );
    118116
    119                 $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
     117        // escape literals
     118        $dateweekday_abbrev = backslashit( $dateweekday_abbrev );
     119        $datemonth = backslashit( $datemonth );
     120        $dateweekday = backslashit( $dateweekday );
     121        $datemonth_abbrev = backslashit( $datemonth_abbrev );
     122        $datemeridiem = backslashit( $datemeridiem );
     123        $datemeridiem_capital = backslashit( $datemeridiem_capital );
     124
     125        // the translated format string
     126        $translateddateformatstring = '';
     127        // the 2 arrays map a format literal to its translation (e. g. 'F' to the escaped month translation)
     128        $tranlateformates = array( 'D', 'F', 'l', 'M', 'a', 'A', 'c', 'r' );
     129        $translations = array(
     130                $dateweekday_abbrev, // D
     131                $datemonth, // F
     132                $dateweekday, // l
     133                $datemonth_abbrev, // M
     134                $datemeridiem, // a
     135                $datemeridiem_capital, // a
     136                'Y-m-d\TH:i:sP', // c
     137                sprintf( '%s, d %s Y H:i:s O', $dateweekday_abbrev, $datemonth_abbrev ), // r
     138        );
     139
     140        // find each format literal that needs translation and replace it by its translation
     141        // respects the escaping
     142        // iterate $dateformatstring from ending to beginning
     143        for ( $i = strlen( $dateformatstring ) - 1; $i > -1; $i-- ) {
     144                // test if current char is format literal that needs translation
     145                $tranlateformateindex = array_search( $dateformatstring[$i], $tranlateformates );
     146
     147                if ( $tranlateformateindex !== false ) {
     148                        // counts the slashes (the escape char) in front of the current char
     149                        $slashescounter = 0;
     150
     151                        // count all slashes left-hand side of the current char
     152                        for ( $j = $i - 1; $j > -1; $j-- ) {
     153                                if ( $dateformatstring[$j] == '\\' )
     154                                        $slashescounter++;
     155                                else
     156                                        break;
     157                        }
     158
     159                        // number of slashes is even
     160                        if ( $slashescounter % 2 == 0 )
     161                                // current char is not escaped, therefore it is a format literal
     162                                $translateddateformatstring = $translations[$tranlateformateindex] . $translateddateformatstring;
     163                        else
     164                                // current char is escaped, therefore it is not a format literal, just add it unchanged
     165                                $translateddateformatstring = $dateformatstring[$i] . $translateddateformatstring;
     166                }
     167                else
     168                        // current char is no a format literal, just add it unchanged
     169                        $translateddateformatstring = $dateformatstring[$i] . $translateddateformatstring;
    120170        }
    121         $timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
    122         $timezone_formats_re = implode( '|', $timezone_formats );
    123         if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
     171
     172        $dateformatstring = $translateddateformatstring;
     173
     174        if ( $gmt )
     175                // get GMT date string
     176                $dateformated = gmdate( $dateformatstring, $timestamp );
     177        else {
     178                // get Wordpress time zone
    124179                $timezone_string = get_option( 'timezone_string' );
    125180                if ( $timezone_string ) {
     181                        // create time zone object
    126182                        $timezone_object = timezone_open( $timezone_string );
    127                         $date_object = date_create( null, $timezone_object );
    128                         foreach( $timezone_formats as $timezone_format ) {
    129                                 if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
    130                                         $formatted = date_format( $date_object, $timezone_format );
    131                                         $dateformatstring = ' '.$dateformatstring;
    132                                         $dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
    133                                         $dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
    134                                 }
    135                         }
     183                        // create date object from time zone object
     184                        $localdateobject = date_create( null, $timezone_object );
     185                        // set time and date of $localdateobject to current $timestamp
     186                        $datecomponents = isset( $datecomponents ) ? $datecomponents : getdate( $timestamp );
     187                        date_date_set( $localdateobject, $datecomponents['year'], $datecomponents['mon'], $datecomponents['mday'] );
     188                        date_time_set( $localdateobject, $datecomponents['hours'], $datecomponents['minutes'], $datecomponents['seconds'] );
     189                        // format date  according to the Wordpress time zone
     190                        $dateformated = date_format( $localdateobject, $dateformatstring );
    136191                }
     192                else {
     193                        // fall back if no Wordpress time zone set
     194                        $dateformated = date( $dateformatstring, $i );
     195                }
    137196        }
    138         $j = @$datefunc( $dateformatstring, $i );
     197
    139198        // allow plugins to redo this entirely for languages with untypical grammars
    140         $j = apply_filters('date_i18n', $j, $req_format, $i, $gmt);
    141         return $j;
     199        $dateformated = apply_filters( 'date_i18n', $dateformated, $req_format, $timestamp, $gmt );
     200
     201        return $dateformated;
    142202}
    143203
    144204/**