0

I have WordPress set to Los Angles time in Settings > General. In my database I have a DATETIME column. When I use $dt = DateTime::createFromFormat('Y-m-d H:i:s', $value_from_db); and then $dt->format('n/j/y @ g:iA T'); it displays the timezone as "UTC". In functions.php if I add date_default_timezone_set( get_option('timezone_string') ); then $dt will output correctly with "PST".

It works, but I didn't think I needed to explicitly set the timezone since I already set it in WordPress. Am I doing something wrong or is this the correct way to set the timezone for my PHP?

1
  • 1
    Actually, you could pass a DateTimeZone instance as the 3rd parameter to DateTime::createFromFormat(), e.g. DateTime::createFromFormat( 'Y-m-d H:i:s', $value_from_db, new DateTimeZone( 'America/Los_Angeles' ) ), but in WordPress you should use date_i18n() or wp_date() (the latter also accepts a custom DateTimeZone instance).
    – Sally CJ
    Commented Jan 16, 2022 at 14:46

1 Answer 1

1

In functions.php if I add date_default_timezone_set( get_option('timezone_string') ); then $dt will output correctly with "PST".

Yes, but, "don’t change PHP time zone with date_default_timezone_set() (this one is hard requirement for correct core operation!)" — https://make.wordpress.org/core/2019/09/23/date-time-improvements-wp-5-3/.

I didn't think I needed to explicitly set the timezone since I already set it in WordPress

WordPress does use what you set there, but WordPress does not set it as the default (PHP) time zone.

WordPress uses it mainly when calculating dates and times (based on a PHP timezone string or a ±HH:MM offset), and thus in order to get the correct calculations, WordPress sets the default time zone to UTC when WordPress loads (see wp-settings.php, line 68).


So instead of overidding the default PHP time zone, you can use date_i18n() to get the same "PST" like you said, i.e. the same date with the correct time zone based on your site's settings. E.g.

$value_from_db = '2022-01-16 09:00:00'; // value hard-coded for testing

// If the site's time zone is America/Los_Angeles, this would output 1/16/22 @ 9:00AM PST
echo date_i18n( 'n/j/y @ g:iA T', strtotime( $value_from_db ) );

/* You'd see the exact same output as when using:
date_default_timezone_set( 'America/Los_Angeles' );
$dt = DateTime::createFromFormat( 'Y-m-d H:i:s', $value_from_db );
echo $dt->format( 'n/j/y @ g:iA T' ); // 1/16/22 @ 9:00AM PST
*/

Or you can use wp_date(), but the documentation says, "Note that, unlike date_i18n(), this function accepts a true Unix timestamp, not summed with timezone offset.", which means if the GMT offset was -8 (8 hours behind GMT/UTC), then wp_date() would return a date that's 8 hours less than the date that's returned by date_i18n().

$value_from_db = '2022-01-16 09:00:00'; // value hard-coded for testing

// If the site's time zone is America/Los_Angeles, this would output 1/16/22 @ 1:00AM PST
echo wp_date( 'n/j/y @ g:iA T', strtotime( $value_from_db ) );

So you should use either date_i18n() or wp_date() depending on your specific requirements.

And you might also be interested in:

  • wp_timezone() — Retrieves the time zone from site settings as a DateTimeZone object, e.g. wp_timezone()->getName() might return America/Los_Angeles.

  • wp_timezone_string() — Retrieves the time zone from site settings as a string, e.g. America/Los_Angeles or -08:00.

2
  • 1
    This is such a great answer, thank you!
    – Gavin
    Commented Jan 17, 2022 at 9:50
  • 1
    I just wanted to say that I constantly come back to this answer as a reference. It's so helpful! Thank you again.
    – Gavin
    Commented Oct 6, 2022 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.