2010-07-22 5 views
67

J'analyse des fichiers journaux tiers contenant la date et l'heure à l'aide de Joda. La date/heure est dans l'un des deux formats différents, en fonction de l'âge des fichiers journaux que j'analyse.Utilisation de l'API Joda Date & Time pour analyser plusieurs formats

Actuellement, j'ai le code comme ceci:

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

Cela fonctionne, mais les conseils de contrevient Joshua Bloch à partir Effective Java 2e édition (Point 57: Utiliser des exceptions uniquement pour des conditions exceptionnelles). Il est également difficile de déterminer si une exception IllegalArgumentException se produit en raison d'une date/heure foirée dans un fichier journal. Pouvez-vous suggérer une approche plus agréable qui n'abuse pas des exceptions?

+0

Peut-être en essayant de deviner le modèle avant de l'utiliser. –

Répondre

126

Vous pouvez créer plusieurs parseurs et les ajouter au constructeur en utilisant DateTimeFormatterBuilder.append méthode:

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

Cela fonctionne parfaitement. Je suppose que JodaStephen voulait dire cela, mais quand j'ai essayé de faire les choses selon ses instructions, l'analyse a échoué. –

+1

Cela ne fonctionne pas par exemple pour '5-5-5' et '5-5-2005' si vous voulez dd-MM-yy et dd-MM-yyyy (impossible d'analyser l'exception). Plus tard, j'ai découvert que dd-MM-yy analyse également jj-MM-yyyy très bien, ce qui a résolu mon problème. – Steven

+0

Etrangement, malgré la variété des surcharges 'append', c'est la seule qui ne lance pas d'exception quand on donne des formats en conflit. – shmosel

6

Malheureusement je ne crois pas que Joda Time ait de telles capacités. Ce serait bien d'avoir une méthode "tryParseDateTime", mais elle n'existe pas.

Je suggère que vous isoliez ce comportement dans votre propre classe (une qui prend une liste de modèles, et essayera chacun à son tour) de sorte que la laideur soit seulement dans un endroit. Si cela cause des problèmes de performances, essayez d'utiliser des heuristiques pour deviner le format à essayer en premier. Par exemple, dans votre cas, si la chaîne commence par un chiffre, c'est probablement le premier modèle.

Notez que DateTimeFormatter s dans Joda Time sont classiquement immuables - vous ne devriez pas en créer un nouveau chaque fois que vous voulez analyser une ligne. Créez-les une fois et réutilisez-les.

+0

Cette réponse donne un sens à mon commentaire. Je suis assez satisfait :) Je suis toujours un débutant, donc je ne le donnerais pas comme réponse –

+0

Merci Jon. Je savais que DateTimeFormatters était immuable, mais pour des raisons de brièveté, mon exemple de code les créait explicitement. Il n'y a pas de problèmes de performances intolérables, donc je pense que je vais faire ce que vous suggérez et créer un cours pour cacher la laideur. –

16

Joda-Time prend en charge ce en permettant à plusieurs parseurs à préciser - DateTimeFormatterBuilder#append

créer simplement vos deux formatteurs à l'aide d'un constructeur et d'appeler toParser() sur chacun. Ensuite, utilisez le générateur pour les combiner en utilisant append.

+4

Whoa! A répondu directement de l'homme lui-même! Aime ton travail Stephen. –

+2

Hmm, j'ai essayé cela, mais Joda-Time semble alors s'attendre à ce que la chaîne analysée corresponde à un modèle qui consiste à la fois les motifs joints ensemble, plutôt que l'un ou l'autre. –

+0

Peut-être que le forum est un meilleur endroit pour voir si c'est un bug - http://sourceforge.net/projects/joda-time/forums/forum/337835 – JodaStephen

Questions connexes