2010-07-22 16 views
67

Estoy analizando archivos de registro de terceros que contienen fecha/hora usando Joda. La fecha/hora está en uno de dos formatos diferentes, según la edad de los archivos de registro que estoy analizando.Usando Joda Date & Time API para analizar múltiples formatos

Actualmente tengo un código como éste:

try { 
    return DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss").parseDateTime(datePart); 
} catch (IllegalArgumentException e) { 
    return DateTimeFormat.forPattern("E, MMM dd, yyyy HH:mm").parseDateTime(datePart); 
} 

esto funciona, pero contraviene el consejo de Joshua Bloch eficaz de Java segunda edición (artículo 57: Utilice las excepciones sólo para condiciones excepcionales). También hace que sea difícil determinar si ocurre una excepción IllegalArgumentException debido a una fecha/hora atormentada en un archivo de registro.

¿Puede sugerir un enfoque más agradable que no abuse de las excepciones?

+0

Tal vez adivinando el patrón antes de usarlo. –

Respuesta

126

Se pueden crear múltiples programas de análisis y añadirlos al constructor mediante el uso de DateTimeFormatterBuilder.append método:

DateTimeParser[] parsers = { 
     DateTimeFormat.forPattern("yyyy-MM-dd HH").getParser(), 
     DateTimeFormat.forPattern("yyyy-MM-dd").getParser() }; 
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, parsers).toFormatter(); 

DateTime date1 = formatter.parseDateTime("2010-01-01"); 
DateTime date2 = formatter.parseDateTime("2010-01-01 01"); 
+1

Esto funciona perfectamente. Supongo que JodaStephen quiso decir esto, pero cuando traté de hacer las cosas de acuerdo con sus instrucciones, el análisis falló. –

+1

Esto no funciona, por ejemplo, '5-5-5' y '5-5-2005' si desea tanto dd-MM-aa como dd-MM-aaaa (no se pudo analizar la excepción). Más tarde descubrí que dd-MM-aa también analiza dd-MM-aaaa bien, así que resolvió mi problema. – Steven

+0

Extrañamente, a pesar de la variedad de sobrecargas 'append', este es el único que no lanza una excepción cuando se le dan formatos conflictivos. – shmosel

6

Lamentablemente, no creo que Joda Time tenga tales capacidades. Sería bueno tener un método "tryParseDateTime", pero no existe.

Sugiero que aísle este comportamiento en su propia clase (una que toma una lista de patrones, y probará cada uno a su vez) para que la fealdad esté solo en un lugar. Si esto está causando problemas de rendimiento, puede intentar usar algunas heurísticas para adivinar qué formato probar primero. Por ejemplo, en su caso si la cadena comienza con un dígito, entonces es probable que sea el primer patrón.

Tenga en cuenta que DateTimeFormatter s en Joda Time son convencionalmente inmutables; no debe crear uno nuevo cada vez que quiera analizar una línea. Créelos una vez y vuelva a utilizarlos.

+0

Esta respuesta da un sentido a mi comentario. Estoy bastante satisfecho :) Todavía soy un principiante, así que no lo daría como respuesta –

+0

Gracias Jon. Sabía que DateTimeFormatters era inmutable, pero en aras de la brevedad en mi código, el ejemplo los creó explícitamente. No hay problemas de rendimiento intolerable, así que creo que haré lo que sugiera y crearé una clase para ocultar lo feo. –

16

Joda-Time soporta esto permitiendo que múltiples programas de análisis que se especificarán - DateTimeFormatterBuilder#append

simplemente crean sus dos formateadores usando un constructor y llaman toParser() en cada uno. A continuación, utilice el generador para combinarlos usando append.

+4

¡Whoa! ¡Respondió directamente del hombre mismo! Amo tu trabajo Stephen. –

+2

Hmm, probé esto, pero Joda-Time parece esperar que la cadena que se está analizando coincida con un patrón que consiste en AMBOS patrones adjuntos, en lugar de uno u otro. –

+0

Quizás el foro sea una mejor ubicación para ver si esto es un error - http://sourceforge.net/projects/joda-time/forums/forum/337835 – JodaStephen

Cuestiones relacionadas