Why do I need to set my PHP timezone when it’s already set in WordPress?

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.