Locale-Sensitive Dates in PHP

I am working on a site at the moment whose front end is in Dutch - and for an English-only speaker, its an education! Most things default to English and I had no idea how to use PHP to work with other languages.

In particular I needed dates like "Donderdag 23 Oktober", and I was sure PHP should know how to do this without me creating arrays for days of the week and months of the year. With some help from my friend (thanks Derick) I discovered that there is a date function in PHP that takes into account the locale of the script, called strftime. The machine needs to have the locale already installed, then you can just do:

         setlocale(LC_TIME, 'nl_NL.UTF-8');
         return ucwords(strftime('%A %e %B',$publish_date));

Setlocale() will return false if the language isn't available on the host system, so its possible to check and maybe try a few likely ones or let the user know. This was useful to me and will work for other languages too - you just need the locale installed and then set with setlocale.

8 thoughts on “Locale-Sensitive Dates in PHP

  1. be very careful with setlocale, read the warning on the php.net page about it and also the comment from the dutch user on 09-Sep-2002 04:02.

  2. We may also supply array as argument to avoid if our locale ID doesn't exist, so php attempt to use another id. Because sometime the locale ID is different between OS.

    Just like what I did on my blog which is only for Indonesian audiences.

    [geshi lang=php]
    setlocale(LC_TIME, array('id_ID', 'id', 'ind'));
    [/geshi]

  3. Seems like everyone is into hint-dropping today instead of actual advice. Maarten's warning is a good one, and refers to http://uk2.php.net/manual/en/function.setlocale.php#25041 where a dutch user had his floating point numbers get mangled going in to mysql because of the differing decimal separator.

    Michal: Interesting hint - this is a Zend Framework project so I might follow up on that. Any resources or examples would be helpful, but I will also rummage so many thanks for mentioning this.

    Firman: The idea of using an array is excellent advice - quite a few people have recommended that I do this since I wrote this post. Thanks for adding your comment :)

    • Resources- obviously ZF Documentation :)
      1. "Zend_Date":http://framework.zend.com/manual/en/zend.date.html
      2. "Zend_Locale_Date":http://framework.zend.com/manual/en/zend.locale.date.datesandtimes.html

      And short example of using Zend_Date with Zend_Locale
      [geshi lang=php]
      // setting default timezone
      date_default_timezone_set('Europe/Warsaw');

      // setting locale according to users`s browser
      $locale = new Zend_Locale(Zend_Locale::BROWSER);
      // creating Zend_Date object AND passing locale object
      $date = new Zend_Date('2008-11-03 18:34:40',null,$locale);
      // outputting date with given format
      echo $date->toString('EEEE, d MMMM YYYY');
      [/lang]
      For polish the output will be: "poniedziałek, 3 listopada 2008, 18:34" and for Dutch: "maandag, 3 november 2008, 18:34"
      The coolest part is that Zend_Locale supplies your app not only with localized names of months, years, and so on, but also with bunch of date formats widely used in different countries :)

      Regards

  4. Great article Lorna. Welcome to strftime() ;-)

    To take Maarten's warning one step further:
    The issue he is refering to is using set_locale() with LC_ALL as the category which is not just inconvenient/confusing with the floating point numbers, but can actually be very dangerous if some of your variable validation code uses CTYPE functions as CTYPE is locale aware as well.

    Lorna's example code where she sets locale specifically for the LC_TIME category *only* however is spot on and will avoid these problems.

  5. Michal, Juliette: Thanks for both adding those words of wisdom from your experiences of correctly using non-English languages successfully. I'm now much better informed :)

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>