SimpleDateFormat Invalid template character error with localized pattern

I am trying to understand some SimpleDateFormat code. In particular, I am trying to use localized template strings in SimpleDateFormat. From javadoc :

SimpleDateFormat also supports localized date and time pattern strings. In these lines, the letters of the patterns described above can be replaced with other language-dependent pattern letters.

It also indicates the constructor of SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols) :

Creates a SimpleDateFormat using pattern data and date format characters.

However, although the getLocalPatternChars() instance represents the expected characters of the pattern, SimpleDateFormat constructors reject patterns containing these 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); } 

outputs the result:

 GuMtkHmsSEDFwWahKzZ Exception in thread "main" java.lang.IllegalArgumentException: Illegal pattern character 't' at java.text.SimpleDateFormat.compile(SimpleDateFormat.java:845) ... 

I get the same result if I replace the last line with " ... new SimpleDateFormat("tt.MM.uuuu", loc); ".

On the other hand, if I create an instance of SimpleDateFormat using any string with an applyLocalizedPattern("tt.MM.uuuu") template, then " applyLocalizedPattern("tt.MM.uuuu") , the localized template is accepted.

So, it seems that you cannot use a localized pattern string in the SimpleDateFormat constructors and you need this two-step initialization. Is this intentional behavior?

+6
source share
1 answer

Unfortunately, the documentation on how to handle localized templates is terrible. Therefore, I studied the source code and conducted my own investigations. Result:

The SimpleDateFormat constructor that accepts a pattern string applies only to non-localized pattern characters, the definition of which is documented as indicated in the javadoc header of the SimpleDateFormat class. These non-localized wildcards 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"; 

To use localized templates , three steps are required (for example, "tt.MM.uuuu", which you consider German but not German, rather it is "TT.MM. JJJJ" - an example of incorrect JDK resources):

  • Define localized template characters through DateFormatSymbols.setLocalPatternChars(...) .
  • Use custom date format characters in a SimpleDateFormat object.
  • Apply a localized datetime template using SimpleDateFormat.applyLocalizedPattern(...)

Then, the localized template will be translated into the internal and official definition of the template symbol.

Usage example (using the correct German template 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 changed the corresponding template patterns y and d to J and T in the line "GyMdkHmsSEDFwWahKzZYuXL" to make a localized definition.

Unfortunately, the JDK resources are obviously not reliable, so my personal opinion is that the whole function can only be used inconveniently and in practice is not very useful.

+3
source

All Articles