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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3307330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:56:36  来源:igfitidea点击:

Using Joda Date & Time API to parse multiple formats

javaparsingexceptionjodatime

提问by Steve McLeod

I'm parsing third party log files containing date/time using Joda. The date/time is in one of two different formats, depending on the age of the log files I'm parsing.

我正在使用 Joda 解析包含日期/时间的第三方日志文件。日期/时间采用两种不同格式之一,具体取决于我正在解析的日志文件的年龄。

Currently I have code like this:

目前我有这样的代码:

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

This works but contravenes Joshua Bloch's advice from Effective Java 2nd Edition (Item 57: Use exceptions only for exceptional conditions). It also makes it hard to determine if an IllegalArgumentException occurs due to a screwed up date/time in a log file.

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

Can you suggest a nicer approach that doesn't misuse exceptions?

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

采纳答案by btiernay

You can create multiple parsers and add them to the builder by using DateTimeFormatterBuilder.appendmethod:

您可以使用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" );

回答by Jon Skeet

Unfortunately I don't believe Joda Time has any such capabilities. It would be nice to have a "tryParseDateTime" method, but it doesn't exist.

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

I suggest you isolate this behaviour into your own class (one which takes a list of patterns, and will try each in turn) so that the ugliness is only in one place. If this is causing performance issues, you might want to try to use some heuristics to guess which format to try first. For example, in your case if the string starts with a digit then it's probably the first pattern.

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

Note that DateTimeFormatters in Joda Time are conventionally immutable - you shouldn't be creating a new one each time you want to parse a line. Create them once and reuse them.

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

回答by JodaStephen

Joda-Time supports this by allowing multiple parsers to be specified - DateTimeFormatterBuilder#append

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

Simply create your two formatters using a builder and call toParser()on each. Then use the builder to combine them using append.

只需使用构建器创建两个格式化程序并分别调用toParser()。然后使用构建器使用append.