我正在尝试了解一些简单的构造代码。特别是我试图在SimpleDateFormat中使用局部模式字符串。来自Javadoc:
SimpleDateFormat还支持局部日期和时间模式字符串。在这些字符串中,上述的图案字母可以用其他依赖性的图案字母代替。
它还指定SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
构造函数:
使用给定的模式和日期格式符号构造简单的format。
但是,尽管getLocalPatternChars()
实例正在呈现预期的模式字符,但SimpleDateFormat的构造函数拒绝包含这些字符的模式:
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);
}
产生输出:
GuMtkHmsSEDFwWahKzZ
Exception in thread "main" java.lang.IllegalArgumentException: Illegal pattern character 't'
at java.text.SimpleDateFormat.compile(SimpleDateFormat.java:845)
...
如果我用" ... new SimpleDateFormat("tt.MM.uuuu", loc);
"替换最后一行,我将获得相同的输出。
另一方面,如果我使用任何英语模式字符串创建一个简单的format实例,则调用" applyLocalizedPattern("tt.MM.uuuu")
",则接受本地化模式。
因此,似乎无法在SimpleDateFormat的构造函数中使用本地化模式字符串,并且需要此两步初始化。这是故意的行为吗?
不幸的是,如何处理本地模式的文档是可怕的。因此,我研究了源代码并进行了自己的调查。结果:
SimpleDateFormat
接受模式字符串的构造函数仅是指未定位的模式字符,其定义是在SimpleDateFormat
类的Javadoc标头中给出的。这些未定位的模式字符也定义为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";
为了使用本地化模式(例如" tt.mm.uuuu"您认为是德语的东西 - 但不是德语,它应该是tt.mm。jjjj" - 错误的JDK资源的示例):
- 通过
DateFormatSymbols.setLocalPatternChars(...)
定义局部模式字符。 - 在您的
SimpleDateFormat
-Object上使用自定义的日期 - 符号。 - 通过
SimpleDateFormat.applyLocalizedPattern(...)
应用本地化日期时间模式
然后,本地化模式将转化为内部和官方模式字符定义。
用法的示例(使用正确的德语模式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
旁注:我已经将适当的模式chars y和d更改为" gymdkhmssedfwwahkzzyuxl"的字符串中的J和T。
不幸的是,JDK资源显然不是可靠的,因此我的个人观点是,整个功能只能以尴尬的方式使用并且在实践中不是很有用。
尽管我同意 @menohochschild对问题的分析,但提出的解决方案似乎比必要的要复杂。SimpleDateFormat
上有一种称为applyLocalizedPattern
的方法,我相信它将达到相同的结果。
String localizedPattern = ... // whatever localized pattern you have e.g. TT.MM.JJJJ
Locale locale = ... // whatever locale you are expecting the localized symbols to be, e.g. GERMAN
// Start with empty pattern (always valid)
SimpleDateFormat df = new SimpleDateFormat("", locale);
// Set the localized pattern (not possible via constructor)
df.applyLocalizedPattern(localizedPattern);
// Now, do whatever you want with that DateFormat object
String canonicalPattern = df.toPattern();
只要localizedPattern
和locale
彼此一致,此技术应适用于此用例。