使用Joda Date&Time API分析多种格式

我使用Jodaparsing包含date/时间的第三方日志文件。 date/时间是两种不同格式之一,具体取决于我正在parsing的日志文件的年龄。

目前我有这样的代码:

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

这是有效的,但是违反了Joshua Bloch对Effective Java 2nd Edition的build议(Item 57:仅在特殊情况下使用exception)。 这也使得很难确定是否由于日志文件中的date/时间错误而导致发生IllegalArgumentException。

你能提出一个更好的方法,不会滥用例外吗?

您可以使用DateTimeFormatterBuilder.append方法创build多个parsing器并将其添加到构build器:

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

Joda-Time通过允许指定多个parsing器来支持这一点 – DateTimeFormatterBuilder#追加

只需使用构build器创build两个格式化器,然后分别调用toParser() 。 然后使用生成器来使用append来合并它们。

不幸的是,我不相信乔达时代有这样的能力。 有一个“tryParseDateTime”方法是很好的,但它不存在。

我build议你把这种行为分解成你自己的类(这个类需要一个模式列表,并且会依次尝试),这样只有一个地方是丑陋的。 如果这导致性能问题,您可能想尝试使用一些启发式来猜测首先尝试哪种格式。 例如,在你的情况下,如果string以数字开头,那么它可能是第一个模式。

请注意,Joda Time中的DateTimeFormatter通常是不可变的 – 每次你想要分析一行时,都不应该创build一个新的。 创build一次并重用它们。