Date formatting in WordPress


Note: This post is quite old. Especially the suggestions under items 2 and 3 are no longer appropriate. More recent tips for date formatting with qTranslate are available here.

After updating to WordPress 2.5, I have – like many others, obviously – experienced the problem that post dates and times were not being localised anymore. Weekday and months names were not translated, and the number of comments was only indicated by an English “x comments”. The frequently recommended setlocale() function did not bring any improvement – and why should it? After all I had already set WordPress as well as PHP to German in the configuration files.

I cannot tell the whys and wherefores, but after some trial and error I found solutions that work at least for me.

1.) Localised comments link

My template used the function comments_popup_link() to generate the link to the comments. In the past, this link was automatically translated into German, e. g. “Keine Kommentare” instead of “No comments”. As of version 2.5, however, that doesn’t work anymore. So in my template I replaced the line

<?php comments_popup_link() ?>

by

<a href="<?php comments_link(); ?>"><?php comments_number(); ?>

In contrast to comments_popup_link(), the function comments_number() dutifully shows the number of comments – and the corresponding words like “keine”, “Kommentar” and “Kommentare” – in German. It does not generate the link to the comments though, so you have to enclose it in a link manually using comments_link().

2.) Localised date display for posts

Instead of the_date() or _e(the_date('l, d F Y, H:i','','',FALSE)), I inserted the following into my template:

_e(
    htmlentities(
        strftime('%A, %e %B %Y at %I:%M %p',
            strtotime(
                the_date('Y/m/d H:i', '', '', FALSE)
            )
        )
    )
)

(Of course, you can simply put this on a single line – i just did it like that for the sake of legibility.)

What does this line of code do?

Roughly spoken, it causes the date not to be output directly by the_date(), but to be forwarded to strftime() for further formatting. For in contrast to the_date(), localisation works perfectly well when using strftime().

For those who want to know exactly:
  1. First the post date is being converted into the format “year/month/day hour:minute” using the_date(), e. g. 2008/05/11 10:30.
  2. This date is then being forwarded to strtotime(), which converts it into a Unix timestamp, e. g. 1210494600.
  3. And that timestamp is finally delivered to strftime(), with which you can format the date according to your regional settings as you like. Woohoo!
  4. Around it all I put a htmlentities() to prevent you from stumbling across a “M?rz” instead of “März”.

The different formatting parameters for strftime() can be found on php.net. The above example '%A, %e %B %Y at %I:%M %p' would output the following: Sunday, 11 May 2008 at 10:30 am

Different localised date formats with qTranslate

If you run a multilingual site using the plugin qTranslate, you can easily specify different date formats for the different languages by means of language tags. For example, I want the German date to be displayed in the format “Sonntag, 11. Mai 2008 um 10:30 Uhr”, while the English one should read “Sunday, 11 May 2008 at 10:30 am”. You simply have to write the whole thing twice with the corresponding language tags and date formats. That will look as follows:

_e(
    '<!--:de-->'.htmlentities(
        strftime('%A, %e. %B %Y um %R Uhr', 
            strtotime(
                the_date('Y/m/d H:i', '', '', FALSE)
            )
        )
    )
    .'<!--:--><!--:en-->'.htmlentities(
        strftime('%A, %e %B %Y at %I:%M %P', 
            strtotime(
                the_date('Y/m/d H:i', '', '', FALSE)
            )
        )
    ).'<!--:-->'
)

qTranslate does provide its own function for post date formatting, which would abbreviate the whole thing:

_e(
    '<!--:de-->'.
    qtrans_formatPostDateTime('%A, %e. %B %Y um %R Uhr')
    .'<!--:--><!--:en-->'.
    qtrans_formatPostDateTime('%A, %e %B %Y at %I:%M %P')
    .'<!--:-->'
)

But unfortunately it didn’t work for me – the result always looked like this: %PM, %Europe/Berlin. %487 %2008 u05 %R 121050249512. Meanwhile I found out that the qTranslate functions can also only deal with a date() format, although the author stated explicitly that the functions would expect a strftime() format. I don’t know why that is – maybe because I am using WordPress 2.5, which is not fully supported by qTranslate so far. Anyway, it does explain the strange output, because when using date(), A stands for a capitalised “AM” or “PM”, e stands for the time zone etc.

As for the comments dates anyhow, I was forced to use the date function provided by qTranslate, because I couldn’t find a native WordPress function, which simply returns the date instead of immediately displaying it. Since I had figured out now how the qTranslate functions really work, I solved this as follows:

_e(
    '<!--:de-->'.htmlentities(
        strftime('%A, %e. %B %Y um %R Uhr', 
            strtotime(
                qtrans_formatCommentDateTime('Y/m/d H:i')
            )
        )
    ).'<!--:--><!--:en-->'.htmlentities(
        strftime('%A, %e %B %Y at %I:%M %P', 
            strtotime(
                qtrans_formatCommentDateTime('Y/m/d H:i')
            )
        )
    ).'<!--:-->'
)

5 responses to “Date formatting in WordPress”

  1. Hallo Ginchen,

    wie hast du denn den Blogtitel durch qtranslate übersetzt???

    Mein header sieht so aus:
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="" type="text/css" media="screen" />


    Anmerkung: Also, erst mal habe ich den Blogtitel im Backend unter “Einstellungen” → “Blogtitel” mit Language-Tags eingetragen. Dort steht also:

    [:de]Ginchens Blog[:en]Ginchen's Blog

    Die Browser-Titelleiste im Format “Ginchens Blog » Name des Posts” entsteht wie folgt:

    <title><?php bloginfo('name'); ?><?php wp_title(); ?></title>

    Und die Überschrift ganz oben auf der Seite, die gleichzeitig ein Link zur Startseite ist, geht so:

    <a href="<?php
    	echo get_settings('home');
    	_e('[:de]/[:en]/en/'); ?>">
    	<?php bloginfo('name'); ?>
    </a>
    

    Dadurch wird je nach Sprache “/en/” ans Ende des Links angehängt oder eben nur ein Slash.

  2. Hi, thanks very much for this, it helped me finish manipulating the post date in WordPress into Spanish.

    Here’s the code that ended up working for me, in case it’s useful for anyone else:

    This gives you the following format: “Jueves, 9 de junio, 2011″


    Ginchen: Damn, my backtick code insertion plugin was disabled … Sorry. Maybe you can post your code again, it should be working now!

Leave a Reply

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