首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SimpleDateFormat错误

SimpleDateFormat错误
EN

Stack Overflow用户
提问于 2011-05-13 08:01:44
回答 4查看 1.9K关注 0票数 1
代码语言:javascript
复制
 /**
 * Validates a date in String data type according to the given date format.
 * 
 * @param validDateFormat
 *           valid date format e.g. YYYY/MM/DD
 * @param strDate
 *            - the date to be validated
 * @return true if the date is valid according to the given format
 */
public static boolean isValidDate(final String strDate, final String validDateFormat) {
    boolean result = true;

    try {
        if (StringUtils.isNotBlank(validDateFormat) && StringUtils.isNotBlank(strDate)
                && StringUtils.isNotEmpty(strDate)) {
            dateValidator = new SimpleDateFormat(validDateFormat, Locale.ENGLISH);
            dateValidator.setLenient(false);
            dateValidator.parse(strDate);


            Log.i(TAG, "***Date entered: "+ strDate +
                    "\nDate parsed back: "+dateValidator.format(dateValidator.parse(strDate)));

            dateValidator = null;
        }
        else
        {
            result = false;
        }
    } catch (final ParseException e) {
        result = false;
    } catch (final IllegalArgumentException e) {
        result = false;
    } catch (final Exception e) {
        result = false;
    }

    return result;
}

例如,当我输入的时候:

代码语言:javascript
复制
boolean result = isValidDate("21/May/201l", "dd/MMM/yyyy");
//result = true

需要提醒的是,输入不是2,011,而是201+字母'l‘。

日志:

代码语言:javascript
复制
  ***Date entered: 21/May/201l
   Date parsed back: 21/May/0201

它不会抛出任何异常,也不会导致错误!

为什么!?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-13 08:37:31

更新:一个想法是对您的输入施加一个相当严格的限制:输入日期字符串和格式字符串必须完全匹配;您可以通过执行以下操作来强制执行此操作:

代码语言:javascript
复制
Date parsed = dateValidator.parse(strDate);
return strDate.equals(dateValidator.format(parsed));

换句话说,验证格式化实际的Date对象返回的字符串是否与传入的字符串相同。这可以确保在格式化字符串中实际存在无效字符时,不会出现错误的正结果(因为在重新格式化日期时,这些字符将被忽略)。

我不确定这是不是一个好的解决方案,因为它可能有过度的限制。我没有仔细考虑过这件事。但不管怎样,这只是个想法。

the documentation of DateFormat.parse (由SimpleDateFormat继承):

该方法不能使用给定字符串的整个文本。

同样,从相同方法的"Throws“部分:

ParseException -如果为,则无法分析指定字符串的开头

注意:如果我用字符串"yyyy-MM-dd“实例化一个SimpleDateFormat,那么它将成功解析字符串"2011-05-12abcdefg":

代码语言:javascript
复制
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(format.parse("2011-05-12abcdefg"));

上面的输出(在我的机器上):

代码语言:javascript
复制
Thu May 12 00:00:00 CDT 2011

因此,基本上它只是尽可能多地解析。

事实上,即使是使用setLenient(false),这也是一种行为,这对我来说确实有点奇怪。

票数 2
EN

Stack Overflow用户

发布于 2011-05-13 08:57:46

您可能需要在此处创建自己的验证器。由于它转换数字的方式,它将返回尾随的f和l的有效日期。

我建议使用String.indexOf的各种迭代来查找"/“的索引位置,然后测试子字符串。至少,对于如何验证日期的数字部分,应该很容易理解。您使用Jan、Feb、Mar等可能会使中间验证复杂化;)

对您的评论进行编辑:

就像-我在编辑模式下看不到你的问题,所以请耐心等待,

代码语言:javascript
复制
String day, month, year;
int div1, div2;
div1=yourDateString.indexOf("/");
div2=yourDateString.indexOf("/",div1);
day =yourDateString.substring(0,div1-1);
month =yourDateString.substring(div1+1,div2-1);
year =yourDateString.substring(div2+1,yourDateString.length()-1);

(我在手机上发帖子,所以我没有完整的编辑器上下文,而且标点符号很麻烦,所以我希望你能理解。这将为您留下每个字段的单独字符串进行测试。)

票数 0
EN

Stack Overflow用户

发布于 2011-05-13 10:10:28

实现这一点的一种方法是在解析时使用ParsePosition。

代码语言:javascript
复制
 `                        String d = "10/31/201lll";
                    ParsePosition pp = new ParsePosition(0);
                    SimpleDateFormat sdf = new SimpleDateFormat("mm/dd/yyyy");
                    sdf.setLenient(false);

                    try {
                            System.out.println(sdf.parse(d, pp));
                            System.out.println(pp.getIndex());
                            System.out.println(d.length());
                    }
                    catch(Exception e){
                            e.printStackTrace();
                    }

`

parsePosition.getIndex()为您提供用于解析的最后一个字符之后的字符的索引。将其与输入字符串的长度进行比较,应该可以告诉您这是绝对解析还是部分解析。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5985912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档