使用Joda日期和时间API解析多种格式


76

我正在使用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);
}

这有效,但违反了有效Java 2nd Edition中Joshua Bloch的建议(条款57:仅在特殊情况下使用例外)。由于日志文件中错误的日期/时间,这也使得很难确定是否发生IllegalArgumentException。

您能提出一种不会滥用异常的更好的方法吗?


也许通过在使用它之前猜测模式。
sly7_7'7

Answers:


146

您可以使用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
这很完美。我想JodaStephen就是这么做的,但是当我尝试按照他的指示做事时,解析失败了。
史蒂夫·麦克劳德

2
如果您同时需要dd-MM-yy和dd-MM-yyyy,则此功能不适用于'5-5-5'和'5-5-2005'(无法解析异常)。后来我发现dd-MM-yy也可以解析dd-MM-yyyy,所以解决了我的问题。
2014年

1
奇怪的是,尽管append重载种类繁多,但在给定格式冲突时,这是唯一不引发异常的重载。
shmosel

17

Joda-Time通过允许指定多个解析器来支持此功能-DateTimeFormatterBuilder#append

只需使用构建器创建两个格式化程序,然后分别调用toParser()它们。然后使用构建器将它们结合使用append


4
哇!直接从男人本人回答!爱你的工作斯蒂芬。
史蒂夫·麦克劳德

3
嗯,我试过了,但是Joda-Time似乎希望解析的字符串匹配一个模式,该模式由两个附加在一起的模式组成,而不是一个或另一个。
史蒂夫·麦克劳德

也许论坛是一个更好的位置,看看这是一个错误- sourceforge.net/projects/joda-time/forums/forum/337835
JodaStephen

7

不幸的是,我不相信Joda Time具有任何这样的功能。拥有“ tryParseDateTime”方法会很好,但是它不存在。

我建议您将此行为隔离到自己的类中(一个接受一系列模式,然后依次尝试每个模式),以便仅将丑陋之处放在一个地方。如果这导致性能问题,您可能想要尝试使用一些启发式方法来猜测首先尝试哪种格式。例如,在您的情况下,如果字符串以数字开头,则可能是第一个模式。

请注意,DateTimeFormatterJoda Time中的s通常是不可变的-每次要解析一行时都不应创建一个新值。一次创建它们并重复使用它们。


这个答案使我的评论有道理。我很满意:)我仍然是一个初学者,所以我不会给出答案
sly7_7 2010年

谢谢乔恩。我知道DateTimeFormatters是不可变的,但是为了简洁起见,在我的代码示例中显式创建了它们。没有任何无法忍受的性能问题,所以我想我会按照您的建议做,并创建一个隐藏丑陋的类。
史蒂夫·麦克劳德

Boo Java缺少诸如DotNet之类的TryParse函数。缺少tryParse例程和通用类型擦除是我的两个最大难题。 docs.oracle.com/javase/tutorial/java/generics/erasure.html
granadaCoder
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.