Localization Tips, Part 2: The Evils of Date Formatting
This is the second entry in a multi-part series about localization.
Every modern platform provides a mechanism for formatting dates. We’ve all dealt with people on the business side who prefer dates formatted as YYYY-mm-dd or dd MMM YY or countless other permutations. The slippering slope of date formatting is that once a date is formatted, it should be formatted correctly for each and every locale that the application supports.
Here is a sample of correct date formatting for 30 common locales:
en_US: Jan 17, 2013
ja_JP: 2013/01/17
fr_FR: 17 janv. 2013
de_DE: 17.01.2013
es_ES: 17/01/2013
it_IT: 17/gen/2013
pt_BR: 17/01/2013
pt_PT: 17/01/2013
nl_NL: 17 jan. 2013
sv_SE: 17 jan 2013
nb_NO: 17. jan. 2013
da_DK: 17/01/2013
fi_FI: 17.1.2013
ru_RU: 17.01.2013
pl_PL: 17 sty 2013
zh_CN: 2013-1-17
zh_TW: 2013/1/17
ko_KR: 2013. 1. 17.
ar_SA: ١٧‏/٠١‏/٢٠١٣
ca_ES: 17/01/2013
cs_CZ: 17. 1. 2013
el_GR: 17 Ιαν 2013
he_IL: 17 בינו 2013
hr_HR: 17. 1. 2013.
hu_HU: 2013.01.17.
ro_RO: 17.01.2013
sk_SK: 17.1.2013
th_TH: 17 ม.ค. 2556
tr_TR: 17 Oca 2013
uk_UA: 17 —Å—ñ—á. 2013
Even after so many managed to agree on the Gregorian calendar system it’s amazing to see the wide variety of date formats. Even if an application only needed to support a few locales, the developer would need to define a few date formats in each translation file and tweak as appropriate for that locale’s conventions. I didn’t know Romanians formatted their dates as 17.01.2013, did you? :)
While nearly every platform’s date formatting APIs provide a way to explicitly set a date format, some also support the notion of “format styles.” These styles define a short, medium and long style for formatting date and time for a given locale. Check out this example from the Flash Globalization APIs.
Specifying a date style of SHORT, MEDIUM or LONG is a very convenient way to ensure that dates are always formatted correctly for the current locale. Here’s an example snippet of Flash code which prints out the MEDIUM version of the current date for the supported locales:
var date:Date = new Date();
for each (var lang:String in Capabilities.languages) {
var locale = new LocaleID(lang);
var localeName = locale.getLanguage() + "_" + locale.getRegion();
var df:DateTimeFormatter = new DateTimeFormatter(localeName, DateTimeStyle.MEDIUM, DateTimeStyle.NONE);
var shortDate:String = df.format(date);
trace(localeName + ": " + shortDate);
}
The output of this script is the same as the snippet of date formats a few paragraphs up. Pretty convenient stuff here. For added flexibility, a developer could also write code to support explicit date formats for certain locales and then fall back to a date style for other locales.
So before you format another date, dig a little deeper into their localization APIs to see what’s available. You might be surprised what you find.