Make WordPress Core

Opened 19 months ago

Last modified 3 months ago

#38771 new enhancement

date_i18n() arguments are misleading in function and documentation

Reported by: Rarst Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.7
Component: Date/Time Keywords: has-patch
Focuses: Cc:


date_i18n() is documented as following:

date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false )

@param string   $dateformatstring Format to display the date.
@param bool|int $unixtimestamp    Optional. Unix timestamp. Default false.
@param bool     $gmt              Optional. Whether to use GMT timezone. Default false.

Second and third arguments are highly problematic.

Let's look at this case:

var_dump( date_default_timezone_get() );     // string(3) "UTC" < WP core resets to this during boot
var_dump( get_option( 'timezone_string' ) ); // string(11) "Europe/Kiev" < site's setting
var_dump( get_option( 'gmt_offset' ) );      // float(2) < numeric offset

$now = strtotime( 'now' );
var_dump( $now ); // int(1478987901)

var_dump( date( DATE_W3C, $now ) );           // string(25) "2016-11-12T21:58:21+00:00" < PHP native UTC time, so far so good

var_dump( date_i18n( DATE_W3C, $now ) );      // string(25) "2016-11-12T21:58:21+02:00" < this is UTC time w/ timezone replaced (!!!)
var_dump( date_i18n( DATE_W3C, $now, true) ); // string(25) "2016-11-12T21:58:21+02:00" < still same, $gmt is meaningless

$now = $now + get_option( 'gmt_offset' ) * HOUR_IN_SECONDS; // "WordPress timestamp"
var_dump( date_i18n( DATE_W3C, $now, true) ); // string(25) "2016-11-12T23:58:21+02:00"  < actually "correct" time


  1. Function does not output correct "local" site time
  2. Actual output consists of GMT time with site's timezone simply replacing real UTC timezone
  3. $gmt argument has no effect since WP always resets timezone to GMT, it's never not GMT under normal operation
  4. For correct output $unixtimestamp needs to be adjusted by timezone offset, making it anything but Unix timestamp.

This is probably way too grown in for any kind of a code change. But at the very least:

  1. $unixtimestamp needs to be thoroughly documented/renamed as WP's own take on timestamp, incompatible with actual Unix timestamps.
  2. $gmt could as well be deprecated since it does nothing and when it does something (timezone changed by third party code) it just further confuses the results.

Attachments (1)

Clarified_date_i18n_args_and_fixed_GMT_one_.patch (2.2 KB) - added by Rarst 3 months ago.
Clarified arguments and fixed current narrow case of what GMT one does.

Download all attachments as: .zip

Change History (6)

#2 @swissspidy
19 months ago

  • Milestone changed from Awaiting Review to Future Release

#3 @purpled
18 months ago

This bit us today when we upgraded wordpress - we were calling date_i18n() and were bit by the fact the gmt flag is no longer respected when passing a timestamp. Please revert to the old behavior or comment better what the parameters do.

#4 @Rarst
3 months ago

Notably date_i18n() will not only consume "WordPress timestamp", but also output one if requested with U format, which is obviously highly inconsistent with date().

I doubt that this can be meaningfully fixed without backwards compatibility break, so probably needs to be thoroughly documented as well.

3 months ago

Clarified arguments and fixed current narrow case of what GMT one does.

#5 @Rarst
3 months ago

  • Keywords has-patch added

I've added patch and fixed what GMT argument does at the moment, which is pretty narrow and useless though.

While it is possible to make GMT work here universally, it would need to wait until all other bugs in the functions are fixed and would be messy on top of already messy implementation.

I think at this point it would make more sense to introduce a new localisation function, based on actual Unix timestamp and feature parity with date(), then deprecate date_i18n().

Note: See TracTickets for help on using tickets.