13

我们最近开始在生产环境中遇到一个奇怪的错误(测试环境工作正常)。

java.lang.IllegalArgumentException:非法模式字符'y'

这是由以下代码引起的

SimpleDateFormat dateFormat = (SimpleDateFormat)DateFormat.getDateInstance();
dateFormat.applyLocalizedPattern("yyyy-MM-dd");

例如,当使用“Y”而不是“y”表示年份时,通常会引发此错误。正如您在上面看到的,这里不是这种情况。我不是 100% 确定服务器上设置的语言环境。Linux env LANG 设置为“de_DE.UTF_8”,因此可能会使用它。

输入 SimpleDateFormat.java 的源代码,我找到了方法translatePattern(String pattern, String from, String to)pattern当from 中不存在任何字符时,这会引发提到的异常。在另一台计算机上进行本地调试时,这些值如下所示

模式=“yyyy-MM-dd”
来自=“GyMdkHmsSEDFwWahKzZ”

从服务器上的异常可以看出,第一个 'y' 不存在于from. from从 获取formatData.getLocalPatternChars(),它是DateFormatSymbols从服务器上的语言环境初始化的。

是否有可用的语言环境可以具有不带“y”的格式?在没有任何代码更改的情况下开始发生此错误,据我所知,没有更改服务器配置。

4

2 回答 2

11

从 SimpleDateFormat javadoc :

SimpleDateFormat 还支持本地化的日期和时间模式字符串。在这些字符串中,上述模式字母可以替换为其他与区域相关的模式字母。

在您的情况下,本地是 DE,因此本地化模式是jjjj-MM-tt. J代表 Jahr 和TTage。

如果您不想处理本地化模式,只需使用SimpleDateFormat.applyPattern("yyyy-MM-dd")

于 2013-05-20T09:19:48.667 回答
8

理想情况下,您应该强制执行模式的语言环境,否则您的模式将需要针对不同的语言环境进行更改,因为 yyyy 适用于 en_US,jjjj 适用于 de_DE 等。相反,仅将 yyyy 和语言环境指定为 en_US,而与您的机器的语言环境无关。

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
System.out.println(format.format(new java.util.Date()));

正如javadoc所说:

使用给定模式和给定语言环境的默认日期格式符号构造 SimpleDateFormat。注意:此构造函数可能不支持所有语言环境。如需全面覆盖,请使用 DateFormat 类中的工厂方法。

参数:

模式:描述日期和时间格式的模式

locale:应使用其日期格式符号的语言环境

这样您就不必担心为运行时区域设置选择什么本地字符串并强制执行特定的区域设置一次。

于 2013-05-20T09:36:57.103 回答