【问题标题】:How to prevent FastDateFormat pattern "yyyy-MM-dd" from parsing String in format "dd-MM-yyyy"如何防止 FastDateFormat 模式“yyyy-MM-dd”解析格式为“dd-MM-yyyy”的字符串
【发布时间】:2014-09-29 20:39:35
【问题描述】:

我有两个用于日期解析的格式字符串:“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 上没有看到任何宽松的设置。

【问题讨论】:

  • 我认为您还需要将此问题标记为其他内容。在Java 中找不到它。

标签: java date


【解决方案1】:

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

所以剩下的唯一选择是:

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

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.*-packages。

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

【讨论】:

  • 您还建议什么其他“更好的库”,我会检查它们。谢谢。
  • @AwkOmo 两个最流行和广泛传播的库是 JSR-310(又名 Java-8 中的内置 java.time-package)和 Joda-Time。我自己的库 Time4J 是未知的,但也提供不可变类型和格式化程序。这三个库都提供了比FastDateFormat 更多的格式化和解析配置选项,例如严格解析。祝你好运。
【解决方案2】:

我的解决方案是格式化解析后的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);
   }
}         

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-09
    • 2021-12-18
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多