日期与SYSDATE的区别 - 值是什么?

时间:2016-05-25 10:05:35

标签: sql oracle plsql

如下所示减去今天的日期会给出正确的输出。

select 
    (TRUNC(to_date('25/05/2016','dd/mm/yyyy'))-TRUNC(to_date('02/01/2016','dd/mm/yyyy')))
from dual;

输出:144天

当采取今天的日期时,下面的广告sysdate应该给144.但显示其他一些值?为什么呢?

select 
    (to_date(SYSDATE,'dd/mm/yyyy'))-(to_date('02/01/2016','dd/mm/yyyy'))
from dual;

输出:-730343(显示一些值)。

2 个答案:

答案 0 :(得分:5)

当你这样做时:

to_date(SYSDATE,'dd/mm/yyyy')

您使用NLS_DATE_FORMAT将SYSDATE(已经是日期)隐式转换为字符串。从似乎是DD-MON-RR的结果。所以你真的在做:

to_date(to_char(SYSDATE,'DD-MON-RR'),'dd/mm/yyyy')

内部部分为您提供字符串'25 -MAY-16'。当您将其转换回yyyy掩码的日期时,您将有一个两位数的年份16,这将被解释为0016年而不是2016年。如果您使用{{1},您实际上会得到您所期望的相反,但这是一个愉快的副作用,它仍然会在不同NLS设置的会话中中断:

rrrr

请注意,使用当前的NLS掩码和隐式转换为字符串,您无法区分第一个和第三个结果;但显而易见的是,在第二和第四个结果中以四位数年份显示它是错误的。

通过隐式转换,您将0016-05-25与2016-01-02进行比较,并且它给出了-730343,因为这是2000年中的天数,根据您预计的差距调整了144天是。

正如Praveen已经说过你不需要使用select to_date(SYSDATE,'dd/mm/yyyy') as bad_nls, to_char(to_date(SYSDATE,'dd/mm/yyyy'), 'YYYY-MM-DD') as bad_string, to_date(SYSDATE,'dd/mm/rrrr') as ok_nls, to_char(to_date(SYSDATE,'dd/mm/rrrr'), 'YYYY-MM-DD') as ok_string from dual; BAD_NLS BAD_STRING OK_NLS OK_STRING --------- ---------- --------- ---------- 25-MAY-16 0016-05-25 25-MAY-16 2016-05-25 作为SYSDATE,如果你想把时间部分设置为午夜,你只能truncate it

to_date()

更一般地说,不要使用两位数年份(唉,似乎我们已经忘记了Y2K的课程了!),并且不依赖于NLS设置。

答案 1 :(得分:1)

您无需使用datesysdate [date]转换为to_date 使用trunc删除sysdate的时间部分。

尝试;

select 
TRUNC(SYSDATE) - (to_date('02/01/2016','dd/mm/yyyy'))
from dual;