为什么 2010/08/15 与 M/d/yy 匹配?

发布于 2024-12-12 20:32:19 字数 2025 浏览 2 评论 0原文

我有一系列有效的日期格式,我想在用户输入的某些文本中检测:

public static final DateFormat[] DATE_FORMATS = {
    new SimpleDateFormat("M/d/yy"),
    new SimpleDateFormat("M.d.yy"),
    new SimpleDateFormat("M-d-yy"),
    new SimpleDateFormat("M/d/yyyy"),
    new SimpleDateFormat("M.d.yyyy"),
    new SimpleDateFormat("M-d-yyyy"),
    new SimpleDateFormat("M/dd/yy"),
    new SimpleDateFormat("M.dd.yy"),
    new SimpleDateFormat("M-dd-yy"),
    new SimpleDateFormat("M/dd/yyyy"),
    new SimpleDateFormat("M.dd.yyyy"),
    new SimpleDateFormat("M-dd-yyyy"),
    new SimpleDateFormat("MM/d/yy"),
    new SimpleDateFormat("MM.d.yy"),
    new SimpleDateFormat("MM-d-yy"),
    new SimpleDateFormat("MM/d/yyyy"),
    new SimpleDateFormat("MM.d.yyyy"),
    new SimpleDateFormat("MM-d-yyyy"),
    new SimpleDateFormat("MM/dd/yy"),
    new SimpleDateFormat("MM.dd.yy"),
    new SimpleDateFormat("MM-dd-yy"),
    new SimpleDateFormat("MM/dd/yyyy"),
    new SimpleDateFormat("MM.dd.yyyy"),
    new SimpleDateFormat("MM-dd-yyyy"),
    new SimpleDateFormat("yyyy/MM/dd"),
    new SimpleDateFormat("yyyy.MM.dd"),
    new SimpleDateFormat("yyyy-MM-dd")
};

通过下面的代码检测日期。 this.searchTokens 是用户输入文本中每个搜索词的数组。

    List<Date> datesFound = new ArrayList<Date>();

    for (String token : this.searchTokens) {

        Date date;

        for (DateFormat dateFormat : DateHelper.DATE_FORMATS) {
            try {
                // Attempt to parse this token as a date.
                date = (Date) dateFormat.parse(token);
                datesFound.add(date);
                break;
            } catch (ParseException e) {
                continue;
            }
        }
    }

此代码验证并将正确的日期添加到我的 List 对象中,除了格式如下的日期之外的任何日期:

  • yyyy/MM/dd
  • yyyy.MM.dd
  • yyyy-MM-dd

在我的一个单元测试中,日期 2010/08/15和 2011/08/15 第一次通过循环匹配 M/d/yy,并成为具有值 Jun 8, 2182 和 Jul 的 Date 对象分别为 8、2182。为什么 DATE_FORMATS 中的第一个 SimpleDateFormat 会接受这样的匹配?位数甚至不匹配...我应该有更好的方法来检测这些日期吗?

I have an array of valid date formats I want to detect in a some text a user enters:

public static final DateFormat[] DATE_FORMATS = {
    new SimpleDateFormat("M/d/yy"),
    new SimpleDateFormat("M.d.yy"),
    new SimpleDateFormat("M-d-yy"),
    new SimpleDateFormat("M/d/yyyy"),
    new SimpleDateFormat("M.d.yyyy"),
    new SimpleDateFormat("M-d-yyyy"),
    new SimpleDateFormat("M/dd/yy"),
    new SimpleDateFormat("M.dd.yy"),
    new SimpleDateFormat("M-dd-yy"),
    new SimpleDateFormat("M/dd/yyyy"),
    new SimpleDateFormat("M.dd.yyyy"),
    new SimpleDateFormat("M-dd-yyyy"),
    new SimpleDateFormat("MM/d/yy"),
    new SimpleDateFormat("MM.d.yy"),
    new SimpleDateFormat("MM-d-yy"),
    new SimpleDateFormat("MM/d/yyyy"),
    new SimpleDateFormat("MM.d.yyyy"),
    new SimpleDateFormat("MM-d-yyyy"),
    new SimpleDateFormat("MM/dd/yy"),
    new SimpleDateFormat("MM.dd.yy"),
    new SimpleDateFormat("MM-dd-yy"),
    new SimpleDateFormat("MM/dd/yyyy"),
    new SimpleDateFormat("MM.dd.yyyy"),
    new SimpleDateFormat("MM-dd-yyyy"),
    new SimpleDateFormat("yyyy/MM/dd"),
    new SimpleDateFormat("yyyy.MM.dd"),
    new SimpleDateFormat("yyyy-MM-dd")
};

Dates are detected through the code below. this.searchTokens is an array of each search term from the user's entered text.

    List<Date> datesFound = new ArrayList<Date>();

    for (String token : this.searchTokens) {

        Date date;

        for (DateFormat dateFormat : DateHelper.DATE_FORMATS) {
            try {
                // Attempt to parse this token as a date.
                date = (Date) dateFormat.parse(token);
                datesFound.add(date);
                break;
            } catch (ParseException e) {
                continue;
            }
        }
    }

This code validates and adds the correct dates to my List object for any date except dates formatted like so:

  • yyyy/MM/dd
  • yyyy.MM.dd
  • yyyy-MM-dd

In one of my unit tests, the dates 2010/08/15 and 2011/08/15 match to M/d/yy the first time through the loop and become Date objects with the values Jun 8, 2182 and Jul 8, 2182, respectively. Why would the first SimpleDateFormat in DATE_FORMATS accept a match like this? The number of digits don't even match up... Is there a better way I should go about detecting these dates?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

可爱暴击 2024-12-19 20:32:19

对您创建的 SimpleDateFormat 对象调用 .setLenient(false)

我认为 M 和 MM 仍然会匹配 1 或 2 位数字。我认为如果这不是您想要的,您必须自己检查(使用正则表达式)。

Call .setLenient(false) on the SimpleDateFormat object you created.

I think M and MM will still both match 1 or 2 digits though. I think you would have to check that yourself (with a regex) if that's not what you want.

清旖 2024-12-19 20:32:19

这对我有用。单独使用 .setLenient(false) 并不能解决问题。

for(int i=0; i < PropDateFormats.length; i++)
{
    try
    {   
    ParsePosition p = new ParsePosition(0);
    PropDateFormats[i].setLenient(false);
        PropagationDate = PropDateFormats[i].parse(_date,p);
    if(p.getIndex() < _date.length())
    {
        log.trace("setPropagationDate.parse("+_date+") failed. Index=["+i+"[ as"+PropagationDate);
    throw new ParseException(_date, p.getIndex());
     }
         log.trace("setPropagationDate.parse("+_date+") passed. Index=["+i+"[  as"+PropagationDate);
          break;
     }

This worked for me. Using .setLenient(false) by itself did not fix the problem.

for(int i=0; i < PropDateFormats.length; i++)
{
    try
    {   
    ParsePosition p = new ParsePosition(0);
    PropDateFormats[i].setLenient(false);
        PropagationDate = PropDateFormats[i].parse(_date,p);
    if(p.getIndex() < _date.length())
    {
        log.trace("setPropagationDate.parse("+_date+") failed. Index=["+i+"[ as"+PropagationDate);
    throw new ParseException(_date, p.getIndex());
     }
         log.trace("setPropagationDate.parse("+_date+") passed. Index=["+i+"[  as"+PropagationDate);
          break;
     }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文