Function Friday #13: use the correct timezone in time-based functions

Function Friday #13

Every Friday, I’m sharing code snippets that I use to customize WordPress. Feedback/suggestions are always welcome! For more information, check out the first post in the series.


Did you know that all time/date-based functions in PHP use UTC time? Based on how often I come across this issue I don’t think many developers do! I certainly didn’t, until I was working on a site that displayed different content based on the current time.

I had a list of upcoming events, created by a basic WP_Query that compared each event’s date & time to the current date & time to determine whether or not the event should display.

Here’s the code I was using:

$current_date = time();
$args = array(
    'meta_key' => 'date_and_time',
    'meta_value' => $current_date,
    'meta_compare' => '>=',
);
$upcoming_events = new WP_Query( $args );

if ( $upcoming_events->have_posts() ) {
    echo '<h2>Upcoming events</h2>
    <ul>';
    // Start the loop
    while ( $upcoming_events->have_posts() ) { $upcoming_events->the_post();
        echo '<li><a href="' . get_permalink() . '">'. get_the_title() .'</a></li>';
    } // End the loop
    echo '</ul>';
}
wp_reset_postdata();

Each event’s date is stored in a custom field called date_and_time, and the current_time variable uses the PHP function time. As soon as an event‘s time is a lower number than the current time, the event is supposed to disappear from the list.

Date stored in custom field

For the sake of simplicity, in this example both dates use Unix timestamps as a date format. It’s a little weird to figure out but it can be converted with an online tool like this one. On an actual client site I’ll use a more human-friendly format.

To my surprise, an event disappeared from the list exactly four hours too early!

The first thing I checked was the Timezone setting (under Settings → General), but it was correctly set to Toronto:

Timezone setting

A closer read of the documentation solved the mystery – the time function always returns the current UTC time, and Toronto time is four hours behind. Now I just had to figure out how to change the timezone that was being used.

The code

Handily, WordPress has a function that does just that:

$current_date = current_time('timestamp');

This does exactly the same thing as PHP’s time function, except it uses the timezone from the General Settings instead of UTC.

It’s also possible to set the timezone for all PHP functions without using WordPress-specific code:

// Set the timezone
date_default_timezone_set('America/Toronto');

// Get the current time
$current_date = time();

// Reset the timezone, to avoid unexpected behaviour later
date_default_timezone_set('UTC');

The PHP manual has a list of available timezones to use in the date_default_timezone_set function. I’d recommend resetting the timezone back to UTC once you’re done with it to avoid some weird WordPress problems further down the line.

If you’re using the current time lots of different places in your code, you might as well wrap it up in a function:

// Create drollic_current_date function
function drollic_current_date() {
    // Set the timezone
    date_default_timezone_set('America/Toronto');

    // Get the current time
    $current_date = time();

    // Reset the timezone, to avoid unexpected behaviour later
    date_default_timezone_set('UTC');

    return $current_date;
}

so you can quickly retrieve it like this:

$current_date = drollic_current_date();

Make sure to add a unique prefix to your function names (like I’ve done with drollic) to avoid plugin/core conflicts.

Where does it go?

The current_time function can be used in any theme file, but if you’re creating a reusable function like drollic_current_date you should put that in your theme’s functions file. There’s more info on where to put your code in the first post in the series.

Resources

Leave a Reply

Your email address will not be published. Required fields are marked *