2013-05-20 4 views
12

Wir hatten vor kurzem einen merkwürdigen Fehler in der Produktionsumgebung (Testumgebungen funktionieren gut).java dateformat illegales Musterzeichen 'y'

java.lang.IllegalArgumentException: Illegal Muster Zeichen 'Y'

Dies wird durch den folgenden Code verursacht wird

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

Dieser Fehler normalerweise ausgelöst wird, wenn beispielsweise 'Y' anstelle von ‚y unter Verwendung von ' für Jahr. Dies ist hier nicht der Fall, wie Sie oben sehen können. Ich bin nicht 100% sicher, das Gebietsschema auf dem Server eingestellt. Linux env LANG ist auf "de_DE.UTF_8" eingestellt, daher wird dies wahrscheinlich verwendet.

Eingabe des Quellcodes von SimpleDateFormat.java Ich fand die Methode translatePattern(String pattern, String from, String to). Dies löst die Ausnahme aus, wenn ein beliebiges Zeichen in pattern nicht in from existiert. Die Werte sieht wie folgt aus, wenn sie lokal Debuggen auf einem anderen Computer

pattern = "yyyy-MM-dd"
from = "GyMdkHmsSEDFwWahKzZ"

Von der Ausnahme auf dem Server ist es offensichtlich, dass die erste ‚y 'existiert nicht in from. from wird von formatData.getLocalPatternChars() abgerufen. Dies ist eine DateFormatSymbols, die vom Gebietsschema auf dem Server initialisiert wird.

Gibt es sogar Gebietsschemas, die Formate ohne 'y' haben könnten? Dieser Fehler ist ohne Codeänderung aufgetreten, und von meinem Wissen her keine Änderung der Serverkonfiguration.

+0

Was ist die genaue JVM, in der Sie laufen? –

+0

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

+0

Und es ist identisch mit dem im Test ausgeführt? –

Antwort

11

Vom Simple javadoc:

Simple unterstützt auch lokale Datum und Uhrzeit Muster Saiten. In diesen Zeichenfolgen können die oben beschriebenen Musterbuchstaben durch andere, Gebietsschema-abhängige Musterbuchstaben ersetzt werden.

In Ihrem Fall ist das lokale DE, so dass das lokalisierte Muster wäre jjjj-MM-tt. J steht für Jahr und T für Tage.

Wenn Sie sich nicht mit lokalisierten Mustern befassen möchten, verwenden Sie einfach SimpleDateFormat.applyPattern("yyyy-MM-dd").

+0

Danke, ich glaube ich habe gerade den Fehler gefunden ... Wir setzen Server Gebietsschema auf Deutsch, aber überschreiben Sie es in einem Init-Servlet auf Schwedisch. Ich denke, die Initalisierung ist möglicherweise abgestürzt, als die Produktion gestern neu gestartet wurde, und wir sind mit dem deutschen Gebietsschema festgefahren! –

+0

http://stackoverflow.com/a/10731242/2105986 könnte das Problem für einige sein. – faizal

7

Im Idealfall sollten Sie das Gebietsschema des Musters erzwingen, andernfalls müsste Ihr Muster für verschiedene Gebietsschemas geändert werden, wie yyyy für en_US, jjjj für de_DE usw. Stattdessen geben Sie nur yyyy und locale als en_US an, unabhängig vom Gebietsschema Ihres Computers.

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

Wie javadoc sagt:

ein Simple Konstruiert auf das Suchmuster und die Standard Datumsformat-Symbole für das jeweilige Gebietsschema verwenden. Hinweis: Dieser Konstruktor kann nicht alle Gebietsschemata unterstützen. Verwenden Sie für die vollständige Abdeckung die Factory-Methoden in der DateFormat-Klasse.

Parameter:

Muster: Das Muster

locale das Datums- und Uhrzeitformat beschreiben: das Gebietsschema, dessen Datumsformat Symbole

diese Weise müssen Sie nicht verwendet werden sollte, sich darum zu kümmern, welche lokale Zeichenfolge für das Gebietsschema für die Laufzeitumgebung ausgewählt werden soll und welche spezifische Ländereinstellung einmal erzwungen werden muss.

+0

Ja, ich stimme zu, der Code, den ich erwähnt habe, stammt aus 2007 und wurde nicht von mir codiert. Wir erzwingen Locale auf unserem Server, aber eine fehlgeschlagene Integration hat den Initialisierungsabsturz verursacht, bevor locale.setDefault (neues Locale ("sv", "SE") aufgerufen wurde, was dazu führte, dass der Serverstandard deutsch verwendet wurde :) –

+0

Wenn Sie Um diesen Code beizubehalten, sollten Sie Initialisierungsfehler fatal machen, damit die Anwendung nicht ausgeführt werden kann. –