【问题标题】:Using Joda Date & Time API to parse multiple formats使用 Joda Date & Time API 解析多种格式
【发布时间】:2011-03-19 10:49:51
【问题描述】:

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

这可行,但违反了来自 Effective Java 2nd Edition 的 Joshua Bloch 的建议(第 57 条:仅在异常情况下使用异常)。这也使得很难确定 IllegalArgumentException 是否由于日志文件中的错误日期/时间而发生。

您能否建议一种不会滥用异常的更好方法?

【问题讨论】:

  • 或许在使用前先猜测模式。

标签: java parsing exception jodatime


【解决方案1】:

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

【讨论】:

  • 这非常有效。我猜 JodaStephen 是这个意思,但是当我尝试按照他的指示做事时,解析失败了。
  • 这不适用于例如 '5-5-5' 和 '5-5-2005' 如果你想要 dd-MM-yy 和 dd-MM-yyyy (无法解析异常)。后来我发现 dd-MM-yy 也可以很好地解析 dd-MM-yyyy,这样就解决了我的问题。
  • 奇怪的是,尽管append 重载多种多样,但这是唯一在给定冲突格式时不会引发异常的重载。
【解决方案2】:

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

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

【讨论】:

  • 哇!直接从男人本人那里回答!喜欢你的工作斯蒂芬。
  • 嗯,我试过了,但是 Joda-Time 似乎期望被解析的字符串匹配一个由两个附加在一起的模式组成的模式,而不是一个或另一个。
  • 也许论坛是一个更好的位置来查看这是否是一个错误 - sourceforge.net/projects/joda-time/forums/forum/337835
【解决方案3】:

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

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

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

【讨论】:

  • 这个答案让我的评论很有意义。我很满意:)我还是初学者,所以我不会给出答案
  • 谢谢乔恩。我知道 DateTimeFormatters 是不可变的,但为了简洁起见,我的代码示例明确地创建了它们。没有无法忍受的性能问题,所以我想我会按照您的建议创建一个类来隐藏丑陋。
  • 因为缺少像 DotNet 这样的 TryParse 函数而嘘 Java。缺少 tryParse 例程和泛型类型擦除是我最大的两个抱怨。 docs.oracle.com/javase/tutorial/java/generics/erasure.html
猜你喜欢
  • 2021-08-10
  • 1970-01-01
  • 2013-08-17
  • 1970-01-01
  • 2011-07-13
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多