计算JPA中两个日期之间的天数

时间:2014-07-28 08:53:12

标签: java postgresql jpa

我需要计算JPA中两个日期之间的天数。

例如:

CriteriaBuilder.construct(
  MyCustomBean.class
  myBean.get(MyBean_.beginDate), //Expression<Date>
  myBean.get(MyBean_.endDate), //Expression<Date>
  myDiffExpr(myBean) //How to write this expression from the 2 Expression<Date>?
);

到目前为止,我试过了:

1)CriteriaBuilder.diff()。但它没有编译,因为此方法需要一些N extends NumberDate不会扩展Number

2)我试图扩展PostgreSQL82Dialect(因为我的目标数据库是PostgreSQL):

public class MyDialect extends PostgreSQL82Dialect {

  public MyDialect() {
    super();
    registerFunction("datediff", 
    //In PostgreSQL, date2 - date1 returns the number of days between them.
    new SQLFunctionTemplate(StandardBasicTypes.LONG, " (?2 - ?1) "));
  }
}

这个编译并且请求成功但返回的结果不一致(从今天到明天之间的78天)。

你会怎么做?

4 个答案:

答案 0 :(得分:2)

JPA 2.1规定在JPQL语句中使用“FUNCTION(funcName,args)”。这允许这样的处理。

答案 1 :(得分:1)

看起来您正在寻找使用JPQL的解决方案来执行SELECT p FROM Period p WHERE datediff(p.to, p.from) > 10之类的查询。

我担心JPQL中没有这样的功能所以我建议使用本机SQL。如果用Hibernate的SQLFunctionTemplate扩展Dialect,你的想法非常聪明。我宁愿将其更改为使用DATE_PART('day', end - start),因为这是使用PostgreSQL实现日期之间差异的方法。

您也可以定义函数in PostgreSQL and using it with criteria function()

'CREATE OR REPLACE FUNCTION "datediff"(TIMESTAMP,TIMESTAMP) RETURNS integer AS \'DATE_PART('day', $1 - $2);\' LANGUAGE sql;'

cb.function("datediff", Integer.class, end, start);

答案 2 :(得分:1)

我终于发现问题来自于参数的顺序不是我预期的那个:

/*
 *(?2 - ?1) is actually equivalent to (? - ?).
 * Hence, when I expect it to evaluate (date2 - date1), 
 * it will actually be evaluated to (date1 - date2)
 */
new SQLFunctionTemplate(StandardBasicTypes.LONG, " (?2 - ?1) "));

我打开了new question以了解此行为是否是错误或功能:

答案 3 :(得分:0)

  

1)CriteriaBuilder.diff()。但是它没有编译,因为这个方法需要一些N扩展Number而Date不会扩展Number。

尝试在每个日期使用mili秒,如下所示。

Date date = new Date()//use your required date
long millisecond = date.getTime();//Returns no of mili seconds from 1 Jan, 1970 GMT

java中的数字长,根据自动装箱你可以使用它。可能这可以帮助。