加快日期模式匹配

时间:2011-10-05 16:20:09

标签: java date design-patterns

我正在编写一些简单的代码,试图推断出一个特定的String是否实际上是一个Java日期,如果是,则确定其格式(模式)。

显然,因为有许多可能的日期格式,确定哪一个适用于字符串需要连续的模式匹配,这实际上是时间和CPU消耗,因为输入字符串也可以具有其他值。

所以,对于名为input的String变量,我最终做了什么,就像

String datePattern;

if (isLikeDate(input))
{
    datePattern = matchAnyOfThePredefinedDatePatterns(input);
}

其中isLike...方法拒绝明显的非日期字符串,match...方法超过约40-50个预定义模式,尝试构造有效的SimpleDateFormat对象。如果input字符串不是每次检查的模式的有效日期,则构造函数会抛出异常。

异常处理会大大减慢速度,但似乎没有避免它。 Apache Commons Date软件包具有类似的性能。

有没有更快的方法来实现这种日期模式匹配?

3 个答案:

答案 0 :(得分:1)

根据模式的复杂程度,您可能希望在尝试之前将每个潜在模式与正则表达式(或手写代码)匹配,以便将其正确解析为日期。例如,如果模式是“yyyyMMddThh:mm:ss”,您可以检查长度,T的位置,冒号的位置,以及其他所有内容都是一个数字,然后再将其传递给日期解析代码。

这种级别的模式匹配可能非常宽松 - 它只是试图排除明确的违反模式。重要的是它不会拒绝任何实际上有效的

缺点是,对于 匹配的任何模式,你正在做两次工作 - 但通过显着减少你抛出的异常数量,这很可能很容易平衡。

编辑:只是为了澄清,您目前正在测试它是否可以匹配任何模式,然后测试所有模式。我建议你有每个模式的正则表达式,并且只尝试解析已经匹配相应正则表达式的模式。

我还建议尝试Joda Time - 它不仅是一个通常更好的API,而且它的模式是线程安全的,因此您可以重用它们。大概你每次有东西要解析时都会创建新的SimpleDateFormat对象。

答案 1 :(得分:1)

您可能会考虑构建类似trie的状态机,有点像使用传入字符串播放弹球盘。这会在非日期相对较快地失败 - 基本上是日期语法解析器。

不确定总是是否更快,或更快 - 足以值得付出努力。

答案 2 :(得分:1)

  

匹配...方法超过了大约40-50个预定义模式,尝试   构造一个有效的SimpleDateFormat对象。

这是否意味着您在每次调用SimpleDateFormat时都在构建新的match个对象?这是非常昂贵的,不要这样做。

保留先前构建的格式对象。如果我记得正确SimpleDateFormat.parse()不是线程安全的,那么将需要一些额外的工作。

当然,您希望首先尝试更高成功率的格式,但我不知道您是否对数据模式有深入了解。