Jeremy Herve Avatar

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


WordPress: display a formatted published date and time

After all these years, I still struggle whenever I have to play with dates in WordPress. Between wp_date(), date_i18n(), get_the_date(), and of course the different date options of PHP, I always find it hard to start. Sprinkle a bit of timezone on top of that, and I find myself having to check the docs every time!

In today’s example, I wanted to generate a localized date and time when a post was published. Something like June 11, 2025, at 8:24 am in English or le 11 juin 2025 à 08h24. Seems simple enough.

Timezones

Let’s start with getting the timezone out of the way. My site is set to the timezone of Paris (UTC +2 right now). Luckily, in WordPress the timezone info is easily accessible via wp_timezone() or wp_timezone_string():

  • wp_timezone_string() gives me Europe/Paris.
  • wp_timezone() gives me a DateTimeZone object with the timezone:
DateTimeZone {#8386
    timezone: Europe/Paris (+02:00),
}

I think I can work with that!

Using DateTimeImmutable (get_post_datetime) and wp_date

I would need to get the post’s full publishing date and time. I could then turn it into a DateTimeImmutable object that would take that timezone into account. Luckily, WordPress gives us post_date in the WP_Post object: 2025-06-11 08:24:00

My first idea was to turn this into a DateTimeImmutable object, passing it wp_timezone():

$post = get_post( $post_id );
$publishing_date = new \DateTimeImmutable(
    $post->post_date,
    wp_timezone()
);
DateTimeImmutable @1749623040 {#8416
    date: 2025-06-11 08:24:00.0 Europe/Paris (+02:00),
}

But it turns out WordPress can do this for us! get_post_datetime() to the rescue:

$post = get_post( $post_id );
$post_datetime = get_post_datetime( $post_id );
DateTimeImmutable @1749623040 {#8399
    date: 2025-06-11 08:24:00.0 Europe/Paris (+02:00),
}

At this point, all what’s left is to format and localize that date, so the result can be used regardless of the site language and date / time format. This is where wp_date() comes in. We’ll provide it with a localized format, and the Unix timestamp from our DateTimeImmutable object.

Let’s build our localized format first. This is the part that I find clunky, and prone to issues because of the translatable string:

$datetime_format = sprintf(
    /* Translators: %1$s is a formatted date, e.g. June 11, 2025. %2$s is a formatted time, e.g. 8:24 am. All other words/letters need to be escaped. */
    __( '%1$s \a\t %2$s', 'my-textdomain' ),
    get_option( 'date_format' ),
    get_option( 'time_format' )
);

On a French site, this may give us \l\e j F Y \à H:i.

Feed that to wp_date(), together with the Unix timestamp from our DateTimeImmutable object:

$formatted_publishing_date = wp_date(
    $datetime_format,
    get_post_datetime( $post_id )->getTimestamp()
);

And you end up with le 11 juin 2025 à 08:24.

This works, but it all seems unnecessarily complicated. 🙂

Réactions sur le Fediverse

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,155 posts
101 followers