繁体   English   中英

两个日期之间的差异

[英]Difference between two dates

我有一个包含以下数据的表

fromDate | toDate
20JAN11  | 29DEC30

这两个日期均为21世纪(即2011年和2030年),但仅存储了最后两个字符。

为什么以下语句(从PL / SQL模块中运行时)针对上述数据总是返回正值

dateDifference := (fromDate - toDate)

如果我从sqlplus运行以下语句,我会得到正确的正确负值。

select to_date('20JAN11','DDMONYY')-to_Date('29DEC30','DDMONYY') from dual;

我记得曾经读过某个地方甲骨文有时会使用错误的世纪,但是我不太记得发生这种情况的确切情况。

假设这些列属于DATE数据类型,情况似乎是这样:Oracle始终以内部格式(包括全年)存储DATE值。 您只看到两位数的年份这一事实与用于将日期转换为要显示的字符串的日期格式有关。 因此,很可能存储的世纪值不是您认为的那样。

尝试以明确的格式选择日期,以查看您实际存储的内容:

SELECT TO_CHAR( fromDate, 'DD-MON-YYYY' ), TO_CHAR( toDate, 'DD-MON-YYYY' )

似乎可以在我的10g数据库中以任何一种方式为我工作:

SQL> set serveroutput on
SQL> 
SQL> DECLARE
  2    d1   DATE := to_date('20JAN11','DDMONRR');
  3    d2   DATE := to_date('29DEC30','DDMONRR');
  4    diff INTEGER;
  5  BEGIN
  6    diff := d1 - d2;
  7    dbms_output.put_line(diff);
  8  END;
  9  /

-7283

PL/SQL procedure successfully completed

SQL> 

编辑:适用于YY而不是RR年格式。

EDIT2:像这样,是什么意思?

SQL> create table t (d1 date, d2 date);

Table created

SQL> insert into t values (to_date('20JAN11','DDMONYY'), to_date('29DEC30','DDMONYY'));

1 row inserted

SQL> commit;

Commit complete

SQL> 
SQL> DECLARE
  2    R    t%ROWTYPE;
  3    diff INTEGER;
  4  BEGIN
  5    SELECT d1, d2
  6      INTO R
  7      FROM t;
  8    diff := R.d1 - R.d2;
  9    dbms_output.put_line(diff);
 10  END;
 11  /

-7283

PL/SQL procedure successfully completed

SQL> 

如@Alex所述,您可能需要验证数据。

无需格式化也可以工作

CREATE  TABLE DATETEST(FROMDATE DATE, TODATE DATE);
insert into DATETEST (fromdate,todate) values (to_date('20Jan11','ddMonrr'),to_date('29DEC30','ddMonrr'));

SELECT TO_CHAR(FROMDATE,'ddMonrrrr hh24:mi:ss') FROMDATE, 
       TO_CHAR(TODATE,'ddMonrrrr hh24:mi:ss') TODATE
  from datetest ;

  /*
FROMDATE           TODATE             
------------------ ------------------ 
20Jan2011 00:00:00 29Dec2030 00:00:00 
*/




set serveroutput on
DECLARE 
 l_FROMDATE DATETEST.FROMDATE%type ;
 L_TODATE DATETEST.TODATE%TYPE;
 dateDifference  number;
BEGIN
--notice -- no formatting just putting them into a variable for test
SELECT FROMDATE, TODATE 
    INTO L_FROMDATE, L_TODATE
from datetest;


DATEDIFFERENCE  := L_FROMDATE - L_TODATE ;

  DBMS_OUTPUT.PUT_LINE('DATEDIFFERENCE  = ' || DATEDIFFERENCE  );
end ;

--DATEDIFFERENCE  = -7283

SELECT FROMDATE-TODATE
from datetest ;

/* --still not formatting
FROMDATE-TODATE        
---------------------- 
-7283  
*/


SELECT (FROMDATE - TODATE) DATEDIFF, 
       TO_CHAR(FROMDATE,'ddMonrrrr') FROMDATE, 
       to_char(todate,'ddMonrrrr') todate 
from (
        SELECT TO_DATE('20JAN11','DDMONYY') FROMDATE, 
               TO_DATE('29DEC30','DDMONYY') TODATE 
          FROM DUAL) 
;
/*

DATEDIFF               FROMDATE  TODATE    
---------------------- --------- --------- 
-7283                  20Jan2011 29Dec2030 

*/

尝试在表上运行第一个查询:

SELECT TO_CHAR(FROMDATE,'ddMonrrrr hh24:mi:ss') FROMDATE, 
       TO_CHAR(TODATE,'ddMonrrrr hh24:mi:ss') TODATE
  from datetest ;

看看这些年是否是您真正期望的。

(编辑:更改为使用两位数年份)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM