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

Ste*_*eod 74 java parsing exception jodatime

我正在使用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);
}
Run Code Online (Sandbox Code Playgroud)

这有效但违反了Joshua Bloch关于Effective Java 2nd Edition的建议(第57项:仅在特殊条件下使用例外).它还使得很难确定是否由于日志文件中的日期/时间搞乱而发生IllegalArgumentException.

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

bti*_*nay 142

您可以使用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" );
Run Code Online (Sandbox Code Playgroud)

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

Jod*_*hen 17

Joda-Time通过允许指定多个解析器来支持这一点 - DateTimeFormatterBuilder#append

只需使用构建器创建两个格式化程序并调用toParser()每个格式化程序.然后使用构建器将它们组合使用append.

  • 哇!直接从男人自己回答!爱你的工作斯蒂芬. (4认同)
  • 嗯,我试过这个,但Joda-Time似乎期望被解析的字符串匹配一个模式,该模式包含附加在一起的模式,而不是一个或另一个. (3认同)

Jon*_*eet 7

不幸的是,我不相信Joda Time有这样的能力.有一个"tryParseDateTime"方法会很好,但它不存在.

我建议你将这种行为隔离到你自己的类中(一个采用模式列表,并将依次尝试每个),以便丑陋只在一个地方.如果这导致性能问题,您可能希望尝试使用一些启发式方法来猜测首先尝试的格式.例如,在您的情况下,如果字符串以数字开头,那么它可能是第一个模式.

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