Support » Plugins » Hacks » Inconsistent behaviour date_i18n()

  • One would expect that date_i18n() adjusts the time to the local time zone. However, the plugin programmer may have to initialize time zone as follows:

    date_default_timezone_set( get_option( 'timezone_string' ) );

    This is only required once, so the behaviour of a plugin may depend upon the fact that maybe another plugin has set it already.

    Would it not be better if date_i18n() should set the timezone on the first call so that simple plugin developers who are not aware of date_default_timezone_set() can rely on consistent behaviour of date_i18n()?

Viewing 5 replies - 1 through 5 (of 5 total)
  • Moderator bcworkz

    (@bcworkz)

    In most cases it will make things worse. Without explicitly setting the default timezone in PHP, instead relying on whatever the system’s default setting is, everything works as expected on my system. Calling date_default_timezone_set( get_option( 'timezone_string' ) ); makes things worse. Calling date_i18n( 'M jS Y H:i' ); will work correctly either way, but using other variants like date( 'M jS Y H:i', current_time('timestamp') ) (which should return a local time) fail.

    System settings should result in time() returning the current GMT timestamp. Any other adjustments are handled by WP. By altering the default timezone for PHP (unless it’s for ‘UTC’), in most cases the offset will not be applied correctly. As developers, we need to take it on faith the system is returning the correct time. If it is not, it’s foolish to second guess it. It’s up to the sysop to get this right, not plugin devs.

    If time() returns the current UTC time, there is no need to set default timezones in PHP, WP will use the values in settings for local adjustments. If time() is not returning the current UTC time, then your system settings need adjusting, do not presume other systems need similar adjustments.

    Thread Starter Jacob N. Breetvelt

    (@opajaap)

    It is not about the current time, but i need a time-zone corrected dat/time display when a UTC timestamp in seconds ( from time() ) is supplied.

    I have read various support topics on this issue, and still can not find a proper way ( except when using date_default_timezone_set() ), to get a properly formatted dat/time display with a given timestamp.
    One suggestion to use get_option( ‘gmt_offset’ ) will not work as it seems that that option does not contain the expected data.

    So, pls tell me the simplest way to get a timestamp display corrected to the timezone as set on the wp settings->general admin page that will always work.

    e.g. when i saved time() five minutes ago, and use

    <?php
    $timestamp = [ saved timestamp ]
    $timezone_format = get_option( 'date_format' ) . ' ' . get_option( 'time_format' );
    echo date_i18n( $timezone_format, $timestamp );
    ?>

    to display it, i want to see my timezones time five minutes ago, not gmt or utc time. So, how should i correct this?

    BTW On line 177,178 of options-general.php it reads:

    // Set TZ so localtime works.
    	date_default_timezone_set($tzstring);

    Why is it allowed there while you do not want me to use it in my plugin?????

    Moderator bcworkz

    (@bcworkz)

    Well, on line 220 the default is set back to UTC. If you are resetting the default the same way once you are finished, then that is fine. I was afraid you were changing it for the rest of the process where it would negatively influence any other subsequent code beyond your own.

    WP basically needs the default zone set to UTC so it can properly manage time related data. Upon initialization, WP explicitly sets UTC in wp-settings.php. (line 52) On options-general.php the default is temporarily changed in order to determine some local daylight/summer time data for display purposes. It is not saving any time related data when the default is not UTC.

    current_time('timestamp') will return the local current time as a UNIX timestamp. current_time('timestamp', true ) will return the current GMT timestamp. You can get a formated date/time string by supplying a PHP format string in place of ‘timestamp’, as in current_time('M jS Y H:i')

    There should be no need to set/reset the default timezone. In fact doing so with current_time() will not work right, it relies on the default set to UTC. Other methods may or may not be affected by changing the default. Timezones and the various date/time functions are very confusing, especially combined with PHP and system settings potentially being wrong as well. time() executed within the WP environment should return the current UTC timestamp. If it does not, the system settings are wrong. Then, assuming the general time settings are correct, current_time('timestamp') will return the correct local timestamp. No need to alter the default PHP timezone.

    Oddly, current_time() uses ‘gmt_offset’ to determine the local time. Which is odd because when we look at that option in the DB with phpMyAdmin, it is empty. Yet I’ve never had problems using current_time(). My guess is WP does some behind the scenes manipulation upon initialization that determines and sets the correct offset. While using current_time() very early might cause problems, using it once WP is initialized will not be a problem.

    Thread Starter Jacob N. Breetvelt

    (@opajaap)

    Thank you for your extensive explanation, but you still do not answer my question how to display a timestamp in local format and local timezone, but i found out in the mean time that i have to code the next fragment for all my plugins that need it ( with different names ). That is why i ask for a wp enhanceent to supply a function like mine ( the archaic case of ‘Etc/GMT’ excluded for clarity ):

    // Covert timestamp to local format, local timezone readable.
    function mypluginname_get_local_date( $timestamp ) {
    
    	date_default_timezone_set( get_option( 'timezone_string' ) );
    	$result = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $timestamp );
    	date_default_timezone_set( 'GMT' );
    	return $result;
    }
    Moderator bcworkz

    (@bcworkz)

    I’m sorry, I guess I misunderstood your question. I thought you wanted just a timestamp in the local timezone. Along with a lot of explanation, I answered with use current_time('timestamp'). Getting the local format is another issue entirely.

    date_i18n(), as far as formats are concerned, uses date translations based on the site’s language setting. Setting the default PHP timezone will not change this. date_default_timezone_set() affects certain PHP date/time functions. date_i18n() relies on translations for formats, it does not use PHP functions at all when composing formats. Timezones cannot possibly dictate languages for date elements.

    To output the current local time in a translated format, just do this:
    echo date_i18n( get_option( ‘date_format’ ) . ‘ ‘ . get_option( ‘time_format’ ));
    No need to set the default timezone, it will not change anything format related. Also, if the specified format does not make use of months or weekdays that need translation, nothing about the format will change.

Viewing 5 replies - 1 through 5 (of 5 total)
  • The topic ‘Inconsistent behaviour date_i18n()’ is closed to new replies.