It may be strange, that I am answering my own question, but I believe, I can add something to the picture.
ICU implementation
Obviously, Java 8 gives you a lot, but there is also something else: ICU4J. This is actually the source of Java original implementation of things like Calendar, DateFormat and SimpleDateFormat, to name a few.
Therefore, it should not be a surprise that ICU's SimpleDateFormat also contains methods like toPattern() or toLocalizedPattern(). You can see them in action here:
DateFormat fmt = DateFormat.getPatternInstance(
DateFormat.YEAR_MONTH,
Locale.forLanguageTag("pl-PL"));
if (fmt instanceof SimpleDateFormat) {
SimpleDateFormat sfmt = (SimpleDateFormat) fmt;
String pattern = sfmt.toPattern();
String localizedPattern = sfmt.toLocalizedPattern();
System.out.println(pattern);
System.out.println(localizedPattern);
}
ICU enhancements
This is nothing new, but what I really wanted to point out is this:
DateFormat.getPatternInstance(String pattern, Locale locale);
This is a method that can return a whole bunch of locale specific patterns, such as:
- ABBR_QUARTER
- QUARTER
- YEAR
- YEAR_ABBR_QUARTER
- YEAR_QUARTER
- YEAR_ABBR_MONTH
- YEAR_MONTH
- YEAR_NUM_MONTH
- YEAR_ABBR_MONTH_DAY
- YEAR_NUM_MONTH_DAY
- YEAR_MONTH_DAY
- YEAR_ABBR_MONTH_WEEKDAY_DAY
- YEAR_MONTH_WEEKDAY_DAY
- YEAR_NUM_MONTH_WEEKDAY_DAY
- ABBR_MONTH
- MONTH
- NUM_MONTH
- ABBR_STANDALONE_MONTH
- STANDALONE_MONTH
- ABBR_MONTH_DAY
- MONTH_DAY
- NUM_MONTH_DAY
- ABBR_MONTH_WEEKDAY_DAY
- MONTH_WEEKDAY_DAY
- NUM_MONTH_WEEKDAY_DAY
- DAY
- ABBR_WEEKDAY
- WEEKDAY
- HOUR
- HOUR24
- HOUR_MINUTE
- HOUR_MINUTE_SECOND
- HOUR24_MINUTE
- HOUR24_MINUTE_SECOND
- HOUR_TZ
- HOUR_GENERIC_TZ
- HOUR_MINUTE_TZ
- HOUR_MINUTE_GENERIC_TZ
- MINUTE
- MINUTE_SECOND
- SECOND
- ABBR_UTC_TZ
- ABBR_SPECIFIC_TZ
- SPECIFIC_TZ
- ABBR_GENERIC_TZ
- GENERIC_TZ
- LOCATION_TZ
Sure, there are quite a few. What is good about them, is that these patterns are actually strings (as in java.lang.String), that is if you use English pattern "MM/d", you'll get locale-specific pattern in return. It might be useful in some corner cases. Usually you would just use DateFormat instance, and won't care about the pattern itself.
Locale-specific pattern vs. localized pattern
The question intention was to get localized, and not the locale-specific pattern. What's the difference?
In theory, toPattern() will give you locale-specific pattern (depending on Locale you used to instantiate (Simple)DateFormat). That is, no matter what target language/country you put, you'll get the pattern composed of symbols like y, M, d, h, H, M, etc.
On the other hand, toLocalizedPattern() should return localized pattern, that is something that is suitable for end users to read and understand. For instance, German middle (default) date pattern would be:
- toPattern(): dd.MM.yyyy
- toLocalizedPattern(): tt.MM.jjjj (day = Tag, month = Monat, year = Jahr)
The intention of the question was: "how to find the localized pattern that could serve as hint as to what the date/time format is". That is, say we have a date field that user can fill-out using the locale-specific pattern, but I want to display a format hint in the localized form.
Sadly, so far there is no good solution. The ICU I mentioned earlier in this post, partially works. That's because, the data that ICU uses come from CLDR, which is unfortunately partially translated/partially correct. In case of my mother's tongue, at the time of writing, neither patterns, nor their localized forms are correctly translated. And every time I correct them, I got outvoted by other people, who do not necessary live in Poland, nor speak Polish language...
The moral of this story: do not fully rely on CLDR. You still need to have local auditors/linguistic reviewers.