我支持一个工作中的通用库,该库对给定的字符串执行许多检查以查看其是否为有效日期。Java API,commons-lang库和JodaTime都具有可以解析字符串并将其转换为日期的方法,以便让您知道它是否实际上是一个有效的日期,但是我希望有一种方法在不实际创建日期对象的情况下进行验证(或使用JodaTime库的日期时间)。例如,这是一段简单的示例代码:
public boolean isValidDate(String dateString) {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
try {
df.parse(dateString);
return true;
} catch (ParseException e) {
return false;
}
}
这对我来说似乎很浪费,我们正在丢弃产生的对象。根据我的基准,在这个公共库中大约有5%的时间用于验证日期。我希望我只是缺少一个明显的API。任何建议都很好!
更新
假设我们始终可以始终使用相同的日期格式(可能是yyyyMMdd)。我确实也考虑过使用正则表达式,但是接下来需要知道每个月的天数,leap年等等。
结果
解析日期一千万次
Using Java's SimpleDateFormat: ~32 seconds
Using commons-lang DateUtils.parseDate: ~32 seconds
Using JodaTime's DateTimeFormatter: ~3.5 seconds
Using the pure code/math solution by Slanec: ~0.8 seconds
Using precomputed results by Slanec and dfb (minus filling cache): ~0.2 seconds
有一些非常有创意的答案,我很感激!我想现在我只需要决定我想要代码看起来像什么的灵活性即可。我要说的是dfb的答案是正确的,因为它纯粹是最快的,这是我最初提出的问题。谢谢!
如果您真的很在意性能,并且您的日期格式真的那么简单,那么只需预先计算所有有效字符串并将它们散列到内存中即可。您上面的格式在2050年之前只有约800万个有效组合
Slanec编辑 -参考实现
此实现取决于您的特定日期格式。它可以适应那里的任何特定日期格式(就像我的第一个答案一样,但要好一些)。
它对dates
1900年到2050年之间的所有数据进行了设置(存储为字符串-其中有54787个),然后将给定的日期与存储的日期进行比较。
一旦dates
设置被创建,它的快速的地狱。快速的微基准测试显示比我的第一个解决方案提高了10倍。
private static Set<String> dates = new HashSet<String>();
static {
for (int year = 1900; year < 2050; year++) {
for (int month = 1; month <= 12; month++) {
for (int day = 1; day <= daysInMonth(year, month); day++) {
StringBuilder date = new StringBuilder();
date.append(String.format("%04d", year));
date.append(String.format("%02d", month));
date.append(String.format("%02d", day));
dates.add(date.toString());
}
}
}
}
public static boolean isValidDate2(String dateString) {
return dates.contains(dateString);
}
PS可以修改为使用Set<Integer>
,甚至可以使用Trove,TIntHashSet
从而大大减少了内存使用(因此允许使用更长的时间跨度),然后性能下降到我的原始解决方案以下的水平。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句