如何防止FastDateFormat模式“yyyy-MM-dd”以“dd-MM-yyyy”格式解析String

时间:2014-09-29 20:39:36

标签: java date

我有两个格式字符串用于日期解析:" yyyy-MM-dd" &安培; " DD-MM-YYYY"我希望FastDateFormat类能够区分这两个类,以便一个人通过ParseException而另一个可以工作。但是两种格式都解析相同的字符串值,其中一个字符串值明显正确解析而另一个字符串值不正确。

我的测试代码显示:

Parsed: "2014-06-06" into Fri Jun 06 00:00:00 EDT 2014 using "yyyy-MM-dd"
Parsed: "2014-06-06" into Sat Dec 05 00:00:00 EST 11 using "dd-MM-yyyy"
Parsed: "06-06-2014" into Sat Dec 05 00:00:00 EST 11 using "yyyy-MM-dd"
Parsed: "06-06-2014" into Fri Jun 06 00:00:00 EDT 2014 using "dd-MM-yyyy"

有没有简单的方法让FastDateFormat根据模式正确处理4位数年份?" 我在FastDateFormat上看不到任何宽松的设置。

2 个答案:

答案 0 :(得分:4)

我可以使用Apache-Common-Lang-library重现您的搜索结果。似乎API没有提供任何官方解决方案,也没有提供最新版本的v3.3.2。通常,一个好的解析器会通过抛出异常拒绝模式dd-MM-yyyy的输入2014-06-06但这里FastDateFormat容忍它,甚至不能设置为像SimpleDateFormat这样的非宽松模式。

所以剩下的唯一选择是:

a)做你自己的黑客(类似于下面的代码示例):

public class ParserDDMMYYYY extends FastDateFormat {
  public static final INSTANCE = 
    new ParserDDMMYYYY("dd-MM-yyyy", TimeZone.getDefault(), Locale.getDefault());

  @Override
  public Date parse(String input) throws ParseException {
    if (input.charAt(4) == '-') {
      throw new ParseException("Invalid format: " + input, 0);
    }
    return super.parse(input);
  }

  // ... more overrides of similar parse methods
}

对于模式yyyy-MM-dd防止dd-MM-yyyy的情况非常相似。

b)或者您更改了日期时间库,因为至少有三个更好的库可用于日期时间处理和格式化。请注意,apache-library仍然基于旧的java.util.* - 和java.text.* - 包。

我也怀疑类FastDateFormat的性能是否真的好得多,与其他日期时间库的不可变版本相比肯定不会更好。例如,我在apache库中看到了一些synchronized-keywords(潜在的锁竞争,不那么现代)。

答案 1 :(得分:0)

我的解决方案是格式化已解析的Date并将String与原始格式进行比较。这比检查特定字符是否在特定位置更通用,但它也更慢。它允许您让用户配置格式。

private final FastDateFormat myDateFormat = FastDateFormat.getInstance("dd-MM-yyyy");

public Date parseDate(String dateString) throws ParseException {
   final Date parsedDate = myDateFormat.parse(dateString);
   if(dateString != timeRangeDateFormat.format(parsedDate)){
      throw new ParseException("Strict mode engaged", 0);
   }
}