Jeremy Herve Avatar

That’s me. And my blog. In English and in French.


Playing with time intervals in WordPress

I’ve recently had to think about calculating time intervals in a little WordPress plugin of mine, and I thought I would share my findings. Maybe some of you will have some ideas on how to improve things even further 🙂

Problem: I want to store the results of an expensive query in a transient for the day.

My first implementation was to set the transient for 24 hours:

set_transient( $transient_key, $query, DAY_IN_SECONDS );

Easy enough! DAY_IN_SECONDS is a default constant provided by WordPress to make those things easier.

That’s not exactly what I want, though. I don’t want data to be cached for 24 hours; I want it to be cached for the rest of the day, i.e. for the amount of time (seconds) left in the day until midnight.

If the query is first run on the site a minute before midnight, I don’t want to cache it for 24 hours; I want that data to be refreshed after midnight, since it’s already going to be the next day.

In my second implementation, I used WordPress’ current_time (reference) and strtotime like so:

$time_now          = (int) current_time( 'timestamp' );
$time_tonight      = (int) strtotime( 'today 24:00' );
$seconds_remaining = $time_tonight - $time_now;

Comparing 2 Unix timestamps seemed simple enough. It works.

However, WPCS wasn’t happy. The use of current_time() with timestamp is discouraged in core, as explained in this GitHub issue.

That led me to a third solution, using the improvements to the Date/Time components that were brought to Core a couple of years ago.

$time_now          = current_datetime();
$time_tonight      = new DateTimeImmutable(
    'today 24:00',
    wp_timezone()
);
$seconds_remaining = $time_tonight->getTimestamp() - $time_now->getTimestamp();

Excellent! No more phpcs warnings, and it works well. Bonus, it’s a tiny bit faster 🙂

Since current_datetime() is also creating a DateTimeImmutable object, I figured it may be easier to read if I were to replace that wrapper:

$time_now          = new DateTimeImmutable(
    'now',
    wp_timezone()
);
$time_tonight      = new DateTimeImmutable(
    'today 24:00',
    wp_timezone()
);
$seconds_remaining = $time_tonight->getTimestamp() - $time_now->getTimestamp();

That seems a bit easier to understand at first glance. It’s also faster.

For fun, here is a last alternative, that’s again a bit faster:

$timezone          = new DateTimeZone( wp_timezone_string() );
$time_now          = new DateTimeImmutable(
    'now',
    $timezone
);
$time_tonight      = new DateTimeImmutable(
    'today 24:00',
    $timezone
);
$seconds_remaining = $time_tonight->getTimestamp() - $time_now->getTimestamp();

I think I’ll keep using wp_timezone(); it’s readable and quick enough. And in the future, I’ll definitely try to use WordPress’ date and time components a bit more!

Would you have done it differently? I’d be curious to have your take on this!

Reactions on the Fediverse and on the ATmosphere

Continuez votre lecture / Keep reading

Discover more posts about or look at some of the posts suggested below.

Jeremy Herve
Jeremy Herve

WordPress, TV Series, music, kids, and board games. I think that’s probably the best way to define me in a few words. 🙂

I work at Automattic where I lead a team building tools for bloggers and creators. I talk a lot about WordPress things, but also about all things open source in general.

I post in English and in French.

I live in Brittany, France, so you’ll also find me sharing pictures from our beautiful region from time to time.

1,241 posts
195 followers