I'm trying to understand some SimpleDateFormat code. In particular I'm trying to use localized pattern strings in SimpleDateFormat. From the javadoc:
SimpleDateFormat also supports localized date and time pattern strings. In these strings, the pattern letters described above may be replaced with other, locale dependent, pattern letters.
It also specifies a SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
constructor:
Constructs a SimpleDateFormat using the given pattern and date format symbols.
However, although getLocalPatternChars()
instance is presenting the expected pattern characters, SimpleDateFormat's constructors are rejecting patterns containing those characters:
public void run() {
Locale loc = new Locale("de", "de");
DateFormatSymbols dfs = new DateFormatSymbols(loc);
String sym = dfs.getLocalPatternChars();
System.out.println(sym);
SimpleDateFormat datefmt = new SimpleDateFormat("tt.MM.uuuu", dfs);
}
produces output:
GuMtkHmsSEDFwWahKzZ
Exception in thread "main" java.lang.IllegalArgumentException: Illegal pattern character 't'
at java.text.SimpleDateFormat.compile(SimpleDateFormat.java:845)
...
I get the same output if I replace the last line with "... new SimpleDateFormat("tt.MM.uuuu", loc);
".
On the other hand, if I create a SimpleDateFormat instance using any Anglicized pattern string, then call "applyLocalizedPattern("tt.MM.uuuu")
", the localized pattern is accepted.
So it appears that one cannot use a localized pattern string in SimpleDateFormat's constructors, and need this two-step initialization. Is this intentional behaviour?
Unfortunately the documentation of how to handle localized patterns is horrible. So I studied the source code and made my own investigations. Result:
The constructor of SimpleDateFormat
accepting a pattern string only refers to the unlocalized pattern characters whose definition is documented as given in the javadoc header of class SimpleDateFormat
. These unlocalized pattern characters are also defined as constant in DateTimeFormatSymbols
:
/**
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
* All locales use the same these unlocalized pattern characters.
*/
static final String patternChars = "GyMdkHmsSEDFwWahKzZYuXL";
Three steps are necessary in order to use localized patterns (like "tt.MM.uuuu" what you believe to be German - but is NOT German, it should rather be "TT.MM.JJJJ" - example for wrong JDK resources):
DateFormatSymbols.setLocalPatternChars(...)
.SimpleDateFormat
-object.SimpleDateFormat.applyLocalizedPattern(...)
Then the localized pattern will be translated to the internal and official pattern character definition.
Example of usage (using the correct German pattern TT.MM.JJJJ):
SimpleDateFormat sdf = new SimpleDateFormat(); // uses default locale (here for Germany)
System.out.println(sdf.toPattern()); // dd.MM.yy HH:mm
System.out.println(sdf.toLocalizedPattern()); // tt.MM.uu HH:mm
DateFormatSymbols dfs = DateFormatSymbols.getInstance(Locale.GERMANY);
dfs.setLocalPatternChars("GJMTkHmsSEDFwWahKzZYuXL");
sdf.setDateFormatSymbols(dfs);
sdf.applyLocalizedPattern("TT.MM.JJJJ");
System.out.println(sdf.toPattern()); // dd.MM.yyyy
System.out.println(sdf.toLocalizedPattern()); // TT.MM.JJJJ
System.out.println(sdf.format(new Date())); // 20.06.2016
Side note: I have changed the appropriate pattern chars y and d to J and T in the string "GyMdkHmsSEDFwWahKzZYuXL" to make a localized definition.
Unfortunately the JDK resources are obviously not reliable so my personal view is that the whole feature can only be used in an awkward way and is not very useful in practice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With