rink.attendant.6
rink.attendant.6

Reputation: 46208

Interationalization of datetimes in PHP

I'm looking at using the IntlDateFormatter class to internationalize dates and times in an application but the manual isn't very clear on what to do.

Suppose I have the following formats of dates, times, and datetimes in the application:

2013-07-01 10:00 PM

July 1 @ 10:00 PM

July 1

10:00 PM

And I want to localize it so that they are displayed as follows in another locale:

2013-07-01 22h00

Juillet 1 à 22h00

Juillet 1

22h00

How do I go about doing this? Do I create eight different IntlDateFormatter objects to handle this because that doesn't seem very intuitive?

$fmt['en-CA']['dt_long'] = new IntlDateFormatter("en_CA", null, null, null, IntlDateFormatter::GREGORIAN, 'Y-M-dd h:mm a');
$fmt['fr-CA']['dt_long2'] = new IntlDateFormatter("fr_CA", null, null, null, IntlDateFormatter::GREGORIAN, 'Y-M-dd H:mm');

$fmt['en-CA']['dt_short'] = new IntlDateFormatter("en_CA", null, null, null, IntlDateFormatter::GREGORIAN, 'MMM d @ h:mm a');
$fmt['fr-CA']['dt_short2'] = new IntlDateFormatter("fr_CA", null, null, null, IntlDateFormatter::GREGORIAN, 'MMM d 'à' H'h'mm');

...

I think I'm doing something wrong because the second and third parameters with the class constants are supposed to be there for a reason, right?

Examples and explanations would be awesome.

Upvotes: 1

Views: 377

Answers (1)

akky
akky

Reputation: 2907

If you want those four specific formats, your code is the correct way. IntlDateFormatter, which wraps ICU library, provides several standard formats, and I believe in each country/language some people agreed them.

If you are okay with their thinking "standards", you may call the class like this,

if (version_compare(PHP_VERSION, '5.3.0', '<')) {
    exit ('IntlDateFormatter is available on PHP 5.3.0 or later.');
}    
if (!class_exists('IntlDateFormatter')) {
    exit ('You need to install php_intl extension.');
}

$mediumShortFormatter = new IntlDateFormatter(
    'fr_CA',
    IntlDateFormatter::MEDIUM,
    IntlDateFormatter::SHORT
);
$longShortFormatter = new IntlDateFormatter(
    'fr_CA',
    IntlDateFormatter::LONG,
    IntlDateFormatter::SHORT
);
$longNoneFormatter = new IntlDateFormatter(
    'fr_CA',
    IntlDateFormatter::LONG,
    IntlDateFormatter::NONE
);
$noneShortFormatter = new IntlDateFormatter(
    'fr_CA',
    IntlDateFormatter::NONE,
    IntlDateFormatter::SHORT
);

$datetime = new DateTime("2013-07-01 22:00:00");
echo $mediumShortFormatter->format($datetime) . "\n";
echo $longShortFormatter->format($datetime) . "\n";
echo $longNoneFormatter->format($datetime) . "\n";
echo $noneShortFormatter->format($datetime) . "\n";

The code above returns me these,

2013-07-01 22:00
1 juillet 2013 22:00
1 juillet 2013
22:00

These are not identical with the ones in your question. If you really need your original formats you showed, yes, you need to specify them one by one.

In Canadian French case, you may be very sure that your formats are correct for your users. But for other locales, will you set those custom formats? If the standard formats are ( even not the ideal, but)acceptable for your users, I recommend you to use those default formats, then you won't need to worry about the correct formats in other languages/countries.

Upvotes: 2

Related Questions