2013-05-20 20 views
12

我們最近在生產環境中出現了一個奇怪的錯誤(測試環境工作正常)。java dateformat非法模式字符'y'

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中的任何字符時提到的異常。在不同的計算機上本地調試從=「GyMdkHmsSEDFwWahKzZ」

從服務器上的例外

圖案=「YYYY-MM-DD」
時的值如下所示,很明顯的是,第一「Y '在from中不存在。 from取自formatData.getLocalPatternChars(),這是從服務器上的語言環境初始化的DateFormatSymbols

是否還有語言環境可用,可能沒有'y'格式?這個錯誤已經開始發生,沒有任何代碼改變,並從我的知識沒有改變服務器配置。

+0

您正在運行的精確JVM是什麼? –

+0

java.vm.specification.vendor:Sun Microsystems Inc. java.runtime.version:1.6.0_37-b06 –

+0

它與測試中運行的相同嗎? –

回答

11

從SimpleDateFormat的Javadoc中:

的SimpleDateFormat還支持本地化日期和時間模式 字符串。在這些字符串中,上面描述的模式字母可能是 被替換爲其他與區域相關的模式字母。

在你的情況下,本地是DE,所以本地化模式將是jjjj-MM-ttJ代表Jahr,代表Tage的T

如果您不想處理局部模式,只需使用SimpleDateFormat.applyPattern("yyyy-MM-dd")即可。

+0

謝謝,我想我只是發現錯誤...我們設置服務器區域設置爲德語,但在init servlet中將其重寫爲瑞典語。我認爲,昨天生產重新啓動後,初創化可能已經崩潰,並且我們陷入了德語區域! –

+0

http://stackoverflow.com/a/10731242/2105986可能是一些問題。 – faizal

7

理想情況下,你應該強制執行模式的區域,否則你的模式將需要更改爲不同的區域設置爲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類中的 工廠方法。

參數:

模式:描述日期和時間格式的模式

區域:其日期格式符號,應使用

這樣,你沒有語言環境擔心爲運行時區域設置選擇什麼本地字符串,並執行一次特定的區域設置。

+0

是的,我同意,我提到的代碼是從2007年開始,而不是由我編碼的。我們在我們的服務器上強制執行locale,但是失敗的集成在locale.setDefault(新語言環境(「sv」,「SE」))被調用之前進行初始化崩潰,導致使用德語的服務器默認值:) –

+0

如果您都是維護上述代碼,您可能希望使初始化錯誤致命,所以應用程序拒絕運行。 –