[Localized] Date/Time format tokens

by Michael S. Kaplan, published on 2006/02/28 04:38 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2006/02/28/540452.aspx


When functions like GetDateFormat and GetTimeFormat work with format picture strings, there is a very limited set of tokens that is considered legal:

Picture Meaning
d Day of month as digits with no leading zero for single-digit days.
dd Day of month as digits with leading zero for single-digit days.
ddd Day of week as a three-letter abbreviation. The function uses the LOCALE_SABBREVDAYNAME value associated with the specified locale.
dddd Day of week as its full name. The function uses the LOCALE_SDAYNAME value associated with the specified locale.
M Month as digits with no leading zero for single-digit months.
MM Month as digits with leading zero for single-digit months.
MMM Month as a three-letter abbreviation. The function uses the LOCALE_SABBREVMONTHNAME value associated with the specified locale.
MMMM Month as its full name. The function uses the LOCALE_SMONTHNAME value associated with the specified locale.
y Year as last two digits, but with no leading zero for years less than 10.
yy Year as last two digits, but with leading zero for years less than 10.
yyyy Year represented by full four or five digits, depending on the calendar used. Thai Buddhist and Korean calendars both have five digit years. The "yyyy" pattern will show five digits for these two calendars, and four digits for all other supported calendars.
yyyyy Behaves identically to "yyyy".
gg Period/era string. The function uses the CAL_SERASTRING value associated with the specified locale. This element is ignored if the date to be formatted does not have an associated era or period string.

Picture Meaning
h Hours with no leading zero for single-digit hours; 12-hour clock.
hh Hours with leading zero for single-digit hours; 12-hour clock.
H Hours with no leading zero for single-digit hours; 24-hour clock.
HH Hours with leading zero for single-digit hours; 24-hour clock.
m Minutes with no leading zero for single-digit minutes.
mm Minutes with leading zero for single-digit minutes.
s Seconds with no leading zero for single-digit seconds.
ss Seconds with leading zero for single-digit seconds.
t One character time-marker string, such as A or P.
tt Multicharacter time-marker string, such as AM or PM.

And it is easy enough to see them in Regional and Language Options:

 

Of course, if you have ever worked with a language version of Windows other than English, you may know that is only part of the story.

Many other language versions of Windows will have different letters defined for the format strings according to Regional and Language Options (for examples you can look here).

But note that this is not locale data, and there is no way to query GetLocaleInfo for what tags are being used in Regional and Language Options.

Now trial and error with the LoadString function being called on the Regional Options binary (intl.cpl) finds the tags rather easily:

ID String
55 H
56 h
57 M
58 m
59 s
60 t
61 d
62 y

Although this has not changed since the functionality was added to Windows, there is of course no guarantee that this will be true of future versions. Just in case you wnted to start using it, be sure to keep that fact in mind. :-)

Now it is hard to imagine the functionality going away since it would break all of the users who have seeing those localized format strings for so long.

And it is perhaps even harder to imagine the format strings returned by GetLocaleInfo or consumed by GetDateFormat and GetTimeFormat changing either, since this would break all of the existing applications.

The "market" for using these localized format pictures is also pretty limited -- basically people writing Regional Options replacements. And how many people are really doing that, anyway?

The one time such a feature might be interesting is in a custom UI language, but at the point where such a thing as that is supported, these strings in Regional Options will of course be availabl to localizers just as they are today (hopefully with some instructions on how to translate these particular strings!).

Of course, not all languages would translate these particular token strings, though it is completely understandable why the English strings may be too confusing for some languages.

But this is one of those interesting features that is well known to many people who use the localized versions of Windows that no one else really knows about....

 

This post brought to you by "d" (U+0064, a.k.a LATIN SMALL LETTER D)


# Anutthara MSFT on 28 Feb 2006 7:08 AM:

Hi Mike - it is interesting to note that the settings support for different locales is limited to date, time, currency and numbers and very minimal string based stuff (if you consider the date manipulation as string based i.e.) Now, we know that addresses and even names are represented differently in different countries like (FirstName, LastName or LastName, FirstName or FirstName.MiddleName.LastName) Is there any reason why these settings are not specific per a defined locale? I am sure apps like One Note or Outlook would require these settings. Is there an API to set/get this kind of format?

# Michael S. Kaplan on 28 Feb 2006 8:33 AM:

Hi Anutthara,

If you asking why address formats are not a part of the Windows locale data, I will be talking about that soon in another post. There is not a function that will set or retrieve this data, though....

# Serge Wautier on 28 Feb 2006 10:34 AM:

Oddly enough, according to your screenshots, the Turkish translation seems to use the same letter (s) for hours and seconds!

# Michael S. Kaplan on 28 Feb 2006 10:55 AM:

Not just looks like Serge -- is!

# Roozbeh Pournader on 28 Feb 2006 1:00 PM:

Well, in the CLDR project (http://www.cldr.info/) we tried to make something out of the very similar mess that CLDR has somehow inherited, that is a string to specify what the locale may prefer for 'h', 'm', 's', etc. Apparently this feature was also available in products from other companies (Apple's Mac OS? IBM's ICU?)

After discussions, we came to the decision that we need to deprecate this altogether and recommend using the original values (that had an English background), since normal users should not really be exposed to something this geeky (the CLDR version is much more complicated: http://www.unicode.org/reports/tr35/#Date_Format_Patterns).

We agreed that if the user is fine with such geeky strings, we can usually safely assume he can learn the mnemonics that have the English background.

# Mihai on 1 Mar 2006 2:17 AM:

Actually, I liked that CLDR feature.
But I was using it in a constructive way (I hope).
The scenario: when accepting a date/time as input, you can use the localized abbreviations for UI (making clear to the user what is expected. Example:

Date of birth: [               ]
                    (jjjj/mm/tt)

And using "dd/mm/yyyy" for validation.

I think having the posibility to retrieve the localized pattern (but not use it for validation or formatting) is a good compromise, usefull, yet with little or no way to abuse it.

Yet, CLDR is just a collection of data, so the potential of abuse is there, is not like an API can restrict what you can do with it.

referenced by

2008/11/25 y? Because it's documented that way!

2006/02/28 A little bit of Turkish delight

go to newer or older post, or back to index or month or day