java - 带有本地化模式的 SimpleDateFormat 非法模式字符错误

标签 java localization simpledateformat

我正在尝试理解一些 SimpleDateFormat 代码。特别是我试图在 SimpleDateFormat 中使用本地化模式字符串。来自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.

它还指定了一个 SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols) 构造函数:

Constructs a SimpleDateFormat using the given pattern and date format symbols.

然而,尽管 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);”,我会得到相同的输出。

另一方面,如果我使用任何英语化模式字符串创建一个 SimpleDateFormat 实例,然后调用“applyLocalizedPattern("tt.MM.uuuu")”,本地化模式将被接受。

因此看来不能在 SimpleDateFormat 的构造函数中使用本地化模式字符串,而需要这两个步骤的初始化。这是故意的行为吗?

最佳答案

不幸的是,有关如何处理本地化模式的文档非常糟糕。所以我研究了源代码并进行了自己的调查。结果:

接受模式字符串的 SimpleDateFormat 的构造函数仅引用未本地化的模式字符,其定义记录在类 SimpleDateFormat 的 javadoc header 中。这些未本地化的模式字符也在 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 资源示例):

  1. 通过 DateFormatSymbols.setLocalPatternChars(...) 定义本地化模式字符。
  2. 在您的 SimpleDateFormat 对象上使用自定义的日期格式符号。
  3. 通过 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

旁注:我已将字符串“GyMdkHmsSEDFwWahKzZYuXL”中的适当模式字符 y 和 d 更改为 J 和 T 以进行本地化定义。

不幸的是,JDK 资源显然不可靠,所以我个人的看法是,整个功能只能以笨拙的方式使用,在实践中不是很有用。

关于java - 带有本地化模式的 SimpleDateFormat 非法模式字符错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37921327/

相关文章:

java - 卢塞恩 : why the highlighting does an extra word splitting ?

mysql - 具有相似可翻译字段的多语言数据库设计

java - 将时间戳保存到数据库时出现错误时间戳格式必须为 yyyy-mm-dd hh :mm:ss[. fffffffff]

Java JDBC 结果集错误,但为什么呢?

java - java 客户端如何从 java RESTful Web 服务访问整数数组

java - DROOLS中 'package'关键字有什么用?

c# - 使用 ExtractToDirectory 方法解压缩会扭曲非拉丁符号

xcode - 使用 Localized.String 在 Xcode 4 中进行本地化

java - DateFormat.format 返回 01 :00:00 with HH:mm:ss format

java - 需要在 java 中以 yyyy/mm/dd 格式显示日期