我正在使用Joda解析包含日期/时间的第三方日志文件。日期/时间是两种不同格式之一,具体取决于我正在解析的日志文件的年龄。
目前我的代码如下:
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的建议(第57项:仅在特殊条件下使用例外)。它还使得很难确定是否由于日志文件中的日期/时间搞乱而发生IllegalArgumentException。
您能否建议一种不会滥用例外的更好方法?
答案 0 :(得分:139)
您可以使用DateTimeFormatterBuilder.append方法创建多个解析器并将其添加到构建器:
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 :(得分:17)
Joda-Time通过允许指定多个解析器来支持这一点 - DateTimeFormatterBuilder#append
只需使用构建器创建两个格式化程序,然后在每个格式化程序上调用toParser()
。然后使用构建器使用append
组合它们。
答案 2 :(得分:7)
不幸的是,我不相信Joda Time有这样的能力。有一个“tryParseDateTime”方法会很好,但它不存在。
我建议你将这种行为隔离到你自己的类中(一个采用模式列表,然后依次尝试),这样丑陋只在一个地方。如果这导致性能问题,您可能希望尝试使用一些启发式方法来猜测首先尝试的格式。例如,在您的情况下,如果字符串以数字开头,那么它可能是第一个模式。
请注意,Joda Time中的DateTimeFormatter
通常是不可变的 - 每次要解析一行时都不应创建新的{J}。创建一次并重复使用它们。