[英]Date difference in date in Oracle and Java
以下问题困扰着我,我找不到任何合理的解释和解决方案。 也许有人可以启发我。
我有一个计算日期差(以天为单位)的应用程序-在搜索掩码和详细信息掩码中。 在第一个掩码中,我使用几天来筛选具有持续时间搜索条件的记录(“搜索掩码”),并使用SQL查询来执行此操作:
WHERE...
...
AND DECODE(TRUNC(to_number(SUBSTR((close_date -
create_date),1,instr(close_date - create_date,' ')))), NULL,
TRUNC(to_number(SUBSTR((systimestamp - create_date),1,instr(systimestamp -
create_date,' ')))), TRUNC(to_number(SUBSTR((close_date -
create_date),1,instr(close_date - create_date,' ')))) ) >=140
AND DECODE(TRUNC(to_number(SUBSTR((close_date -
create_date),1,instr(close_date - create_date,' ')))), NULL,
TRUNC(to_number(SUBSTR((systimestamp - create_date),1,instr(systimestamp -
create_date,' ')))), TRUNC(to_number(SUBSTR((close_date -
create_date),1,instr(close_date - create_date,' ')))) ) <=140
在这种特殊情况下,我尝试找出持续时间为140天的所有记录。
在第二个遮罩(详细信息)中,我显示记录详细信息,包括其持续时间。 这是通过以下Java代码完成的:
public static Integer getDuration(Date caseDate, Date closeDate) {
Date beginDate = caseDate;
Date endDate = (closeDate != null)? closeDate: new Date();
long difference = endDate.getTime() - beginDate.getTime();
int daysDiff = (int) (difference / (24.0 * 60 * 60 * 1000));
return new Integer(daysDiff);
}
我的问题是,当我搜索时,会找到一些确实符合搜索条件的记录。 例如,我找到了4条记录,所有记录都有140天的持续时间。 根据Oracle的说法。 但是,当我为其中一些打开“详细信息”蒙版时,我得到的时间为139天。 因此,Java和Oracle以某种方式以不同的方式计算日期差。 似乎在Oracle中已经进行了一些四舍五入,但是我找不到发生这种情况的地方。 因此,任何建议都将有所帮助。 谢谢!
问候,阿拉迈克
日期可以相同,但时间可以不同。 毫秒计算结果为139天。 (java)
我建议不要使用毫秒,而是使用天数进行计算。
就像是
public long daysBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}}
要么
/**
*
* @param c1 from
* @param c2 to
* @return amount of days between from and to
*/
public int diff(Calendar c1, Calendar c2) {
int years = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
if (years == 0) {
return c2.get(Calendar.DAY_OF_YEAR) - c1.get(Calendar.DAY_OF_YEAR);
} else {
Calendar endOfYear = Calendar.getInstance();
endOfYear.set(Calendar.YEAR, c1.get(Calendar.YEAR));
endOfYear.set(Calendar.MONTH, 11);
endOfYear.set(Calendar.DAY_OF_MONTH, 31);
int days = endOfYear.get(Calendar.DAY_OF_YEAR) - c1.get(Calendar.DAY_OF_YEAR);
for (int i=1;i <years;i++) {
endOfYear.add(Calendar.YEAR, 1);
days += endOfYear.get(Calendar.DAY_OF_YEAR);
}
days += c2.get(Calendar.DAY_OF_YEAR);
return days;
}
}
旁注:第一个示例比第二个示例稍微慢一些,但是如果仅是很小的差异,则可以忽略。
我以相同的方式计算,但我使用dayDiff的时间不长于整数。 所以也尝试一下,不要抛弃它。 它应该工作正常。
这里的问题是,您认为这两个列都是DATE列,而这两个列中至少有一个确实是TIMESTAMP列。 从另一个日期中提取一个日期时,您会得到一个NUMBER。 但是,当您从时间戳记中提取日期时,反之亦然,则会得到一个INTERVAL。
一个例子
具有DATE和TIMESTAMP的表:
SQL> create table mytable (close_date,create_date)
2 as
3 select date '2010-11-01', systimestamp from dual union all
4 select date '2010-11-11', systimestamp from dual union all
5 select date '2010-12-01', systimestamp from dual
6 /
Table created.
SQL> desc mytable
Name Null? Type
----------------------------------------- -------- ----------------------------
CLOSE_DATE DATE
CREATE_DATE TIMESTAMP(6) WITH TIME ZONE
从DATE列中提取一个TIMESTAMP,导致一个INTERVAL:
SQL> select close_date - create_date
2 from mytable
3 /
CLOSE_DATE-CREATE_DATE
---------------------------------------------------------------------------
+000000130 11:20:11.672623
+000000140 11:20:11.672623
+000000160 11:20:11.672623
3 rows selected.
无需摆弄TO_NUMBER和SUBSTR。 只需使用EXTRACT函数从一个间隔中获取所需的组件:
SQL> select extract(day from (close_date - create_date))
2 from mytable
3 /
EXTRACT(DAYFROM(CLOSE_DATE-CREATE_DATE))
----------------------------------------
130
140
160
3 rows selected.
问候,罗布。
这是一个带有两个TIMESTAMPS的示例,该示例显示INTERVAL被截断而不是四舍五入:
SQL> create table mytable (close_date,create_date)
2 as
3 select to_timestamp('2010-11-01','yyyy-mm-dd'), trunc(systimestamp,'dd') + interval '6' hour from dual union all
4 select to_timestamp('2010-11-11','yyyy-mm-dd'), trunc(systimestamp,'dd') + interval '12' hour from dual union all
5 select to_timestamp('2010-12-01','yyyy-mm-dd'), trunc(systimestamp,'dd') + interval '18' hour from dual
6 /
Table created.
SQL> desc mytable
Name Null? Type
----------------------------------------- -------- ----------------------------
CLOSE_DATE TIMESTAMP(9)
CREATE_DATE DATE
SQL> select close_date - create_date
2 from mytable
3 /
CLOSE_DATE-CREATE_DATE
---------------------------------------------------------------------------
+000000130 18:00:00.000000000
+000000140 12:00:00.000000000
+000000160 06:00:00.000000000
3 rows selected.
SQL> select extract(day from (close_date - create_date))
2 from mytable
3 /
EXTRACT(DAYFROM(CLOSE_DATE-CREATE_DATE))
----------------------------------------
130
140
160
3 rows selected.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.