首页 > 解决方案 > 如何检查 Java 日期类型的有效性?

问题描述

我写了两个简单的函数来获取我在 MySQL 表中的日期值。开始日期和结束日期列都是Date数据类型。所以,在我的这两个函数中是这样的:

public Date get_startdate(long nodeid,String ts) {
    try {
        String sql="Select STARTDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
        if (em == null) {
             throw new Exception("could not found URL object.");
        }
        return (Date) em.createNativeQuery(sql).getSingleResult();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public Date get_enddate(long nodeid,String ts) {
    try {
        String sql="Select ENDDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
        if (em == null) {
            throw new Exception("could not found URL object.");
        }
        return (Date) em.createNativeQuery(sql).getSingleResult();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

现在我像这样在我的主页中调用这些函数,我想检查日期条件,如果 URL 在这两个日期之间,那么它应该是有效的并做一些事情。我在下面强调我的意思:

Date file_getstartdate=fileFacade1.get_startdate(fileID,hash);
Date file_getenddate=fileFacade1.get_enddate(fileID,hash);

String currentDate = CoreUtil.parseDate(new Date());

if( file_getstartdate<= currentDate<= file_getendDate){
    //URL is valid, do something
}else {
    //do nothing
}

我存储在表格中的日期是格式YYYY-MM-DD,我面临的问题是在if上面的语句中进行比较。我不能使用这些运算符进行检查。有没有办法实现我的愿望?

标签: javadate-comparisondate

解决方案


不要使用字符串连接来构造 SQL 查询

这很容易受到 SQL 注入的影响,而且非常危险:

String sql="Select STARTDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
...
return (Date) em.createNativeQuery(sql).getSingleResult();

假设em引用一个EntityManager对象,那么您可以构建一个Criteria基于查询,或者如果您确实需要坚持使用本机 SQL,那么您应该使用PreparedStatement代替。

对于您的比较问题,您有三个问题:

  • 您正在尝试比较两种不同的类型(StringDate)。
  • 您正在尝试使用只能用于比较原语但不能用于比较对象 ( <=) 的运算符。
  • 您将条件写成数学语句而不是编程条件语句(a <= b <= c不是有效的 Java 语句。它必须是a <= b && b <= c)。

这是使用Date该类进行比较的一种方法(请注意,LocalDate如果您有选择,Java 8 是一个更好的类)。

Date fileStartDate = fileFacade1.get_startdate(fileID, hash);
Date fileEndDate = fileFacade1.get_enddate(fileID, hash);

Date currentDate = new Date();

if (fileStartDate.before(currentDate) && fileEndDate.after(currentDate) {
  ...

回应您的评论

好的,但是使用preparedStatement 是否有助于此SQL 注入。实体管理器是否阻止注入?有人告诉我不要使用preparedstatement,还有其他选择吗?

如果有人告诉您使用字符串连接(代码的+nodeid++ts +部分)而不是使用 PreparedStatement 进行本机查询,那么他们是错误的。EntityManager 不会保护您免受上述代码中的注入,但 PreparedStatement 以及更改查询的构造方式会。

PreparedStatement 看起来像

String url = "f0=" + nodeid + "&ts=" + ts;
PreparedStatement preparedStatement = connection.prepareStatement("Select STARTDT FROM urllink WHERE URL= ?");
preparedStatement.setString(1, url);
ResultSet resultSet = preparedStatement.executeQuery();

如果您被告知使用 anEntityManager而不是编写本机 SQL,那么这实际上是个好建议。您需要使用Criteria抽象构造查询。如何做到这一点可能是一个单独的问题。


推荐阅读