2010-07-22 8 views
67

Sto analizzando file di registro di terze parti contenenti data/ora utilizzando Joda. La data/ora è in uno di due formati diversi, a seconda dell'età dei file di registro che sto analizzando.Utilizzo dell'API Joda Date & Time per analizzare più formati

Attualmente ho il codice come questo:

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); 
} 

questo funziona, ma contravviene il consiglio di Joshua Bloch da Effective Java 2nd Edition (Articolo 57: utilizzare le eccezioni solo per le condizioni eccezionali). Inoltre rende difficile determinare se si verifica un IllegalArgumentException a causa di una data/ora sbagliata in un file di registro.

Potete suggerire un approccio migliore che non usi male le eccezioni?

+0

Forse cercando di indovinare il modello prima di utilizzarlo. –

risposta

126

È possibile creare più parser e aggiungerli al costruttore utilizzando DateTimeFormatterBuilder.append metodo:

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

Questo funziona perfettamente. Immagino che JodaStephen intendesse questo, ma quando ho provato a fare le cose seguendo le sue istruzioni l'analisi è fallita. –

+1

Questo non funziona per esempio '5-5-5' e '5-5-2005' se si desidera sia dd-MM-yy che gg-MM-aaaa (non è stato possibile analizzare l'eccezione). Più tardi ho scoperto che dd-MM-yy analizza anche gg-MM-yyyy bene, in modo da risolvere il mio problema. – Steven

+0

Stranamente, nonostante la varietà di overload 'append', questo è l'unico che non genera un'eccezione quando vengono forniti formati in conflitto. – shmosel

6

Purtroppo non credo che Joda Time abbia tali capacità. Sarebbe bello avere un metodo "tryParseDateTime", ma non esiste.

Ti suggerisco di isolare questo comportamento nella tua classe (uno che prende una lista di schemi e proverà ciascuno a turno) in modo che la bruttezza sia solo in un posto. Se questo sta causando problemi di prestazioni, potresti provare a utilizzare alcune euristiche per indovinare quale formato provare prima. Ad esempio, nel tuo caso se la stringa inizia con una cifra, probabilmente è il primo schema.

Si noti che DateTimeFormatter s in Joda Time sono convenzionalmente immutabili: non si dovrebbe crearne uno nuovo ogni volta che si desidera analizzare una linea. Creali una volta e riutilizzali.

+0

Questa risposta dà un senso al mio commento. Sono abbastanza soddisfatto :) Sono ancora un principiante, quindi non lo darei come risposta –

+0

Grazie Jon. Sapevo che DateTimeFormatters era immutabile, ma per brevità nel mio esempio di codice li ho creati esplicitamente. Non ci sono problemi di prestazioni intollerabili, quindi penso che farò quello che suggerisci e creare una classe per nascondere la bruttezza. –

16

Joda-Time supporta questo permettendo molteplici parser da specificare - DateTimeFormatterBuilder#append

è sufficiente creare i tuoi due formattatori utilizzando un costruttore e chiamare toParser() su ciascuno. Quindi usa il builder per combinarli usando append.

+4

Whoa! Risposta direttamente dall'uomo stesso! Adoro il tuo lavoro Stephen. –

+2

Hmm, ho provato questo, ma Joda-Time sembra quindi aspettarsi che la stringa venga analizzata in modo che corrisponda a un pattern costituito da ENTRAMBI i pattern uniti insieme, piuttosto che uno OR l'altro. –

+0

Forse il forum è una posizione migliore per vedere se questo è un bug - http://sourceforge.net/projects/joda-time/forums/forum/337835 – JodaStephen

Problemi correlati