Tom Kyte suggests使用EXTRACT
来区别对待:
extract( day from (x-y) )*24*60*60+
extract( hour from (x-y) )*60*60+
...
这似乎更难以阅读并且比这更慢,例如:
( CAST( x AS DATE ) - CAST( y AS DATE ) ) * 86400
那么,以秒为单位获取两个时间戳之间差异的方法是什么?谢谢!
答案 0 :(得分:17)
“最佳实践”
无论你做什么,都将它包装在一个函数中,例如seconds_between (from_date, to_date)
- 不管它是怎么做的(选择最有效的方法) - 那么你的代码在做什么就很明显了。
<强>性能强>
我在笔记本电脑(WinXP)上使用下面的测试用例测试了11gR1上的两种方法。似乎CAST选项是最快的。 (t1是基线,t2使用extract
方法,t3使用cast
方法)
t1 (nothing) 3
t2 (extract) 338
t3 (cast) 101
t1 (nothing) 3
t2 (extract) 336
t3 (cast) 100
测试脚本
declare
x TIMESTAMP := SYSTIMESTAMP;
y TIMESTAMP := TRUNC(SYSDATE);
n PLS_INTEGER;
lc CONSTANT PLS_INTEGER := 1000000;
t1 PLS_INTEGER;
t2 PLS_INTEGER;
t3 PLS_INTEGER;
begin
t1 := DBMS_UTILITY.get_time;
for i in 1..lc loop
n := i;
end loop;
t1 := DBMS_UTILITY.get_time - t1;
t2 := DBMS_UTILITY.get_time;
for i in 1..lc loop
n := extract(day from (x-y))*24*60*60
+ extract(hour from (x-y))*60*60
+ extract(minute from (x-y))*60
+ extract(second from (x-y));
end loop;
t2 := DBMS_UTILITY.get_time - t2;
t3 := DBMS_UTILITY.get_time;
for i in 1..lc loop
n := ( CAST( x AS DATE ) - CAST( y AS DATE ) ) * 86400;
end loop;
t3 := DBMS_UTILITY.get_time - t3;
dbms_output.put_line('t1 (nothing) ' || t1);
dbms_output.put_line('t2 (extract) ' || t2);
dbms_output.put_line('t3 (cast) ' || t3);
end;
答案 1 :(得分:8)
替代:
我发现这也可以在几秒钟内获得差异,包括毫秒
它甚至可以节省“夏令时”的时区,而提取方法会有问题。
不幸的是,t1和t2之间的差异是有限的,结果是正确的。将时间戳转换为日期格式不是一种选择,因为秒的分数会丢失。
select (sysdate + (t2 - t1)*1000 - sysdate) * 86.4 from
(select
to_timestamp('2014-03-30 01:00:10.111','YYYY-MM-DD HH24:MI:SS.FF') at time zone 'MET' t1,
to_timestamp('2014-03-30 03:00:10.112','YYYY-MM-DD HH24:MI:SS.FF') at time zone 'MET' t2
from dual);
答案 2 :(得分:3)
我一直使用第二种方式,即比较DATE(给出天数差异,小数部分),乘以你想要给出的小时数,分钟数,秒数或不管。
我认为这很好,也很容易阅读。
答案 3 :(得分:1)
就个人而言,我发现:
extract(day from (x-y))*24*60*60 + ... + extract(second from (x-y))
目的比......更清楚
( CAST( x AS DATE ) - CAST( y AS DATE ) ) * 86400
以秒为单位获得差异。
Tom的方法需要多点击键,但目的很明确。
答案 4 :(得分:0)
方便快捷地使用:
extract( day from(t2 - t1)*24*60*60)
示例:
with dates as (
select
to_timestamp('2019-06-18 22:50:00', 'yyyy-mm-dd hh24:mi:ss') t1
, to_timestamp('2019-06-19 00:00:38', 'yyyy-mm-dd hh24:mi:ss') t2
from dual
)
select
extract( day from(t2 - t1)*24*60*60) diff_in_seconds
from dates
;
输出:
DIFF_IN_SECONDS
---------------
638
答案 5 :(得分:-3)
to_number(to_char(t2, 'yyyymmddhh24missff')) - to_number(to_char(t1, 'yyyymmddhh24missff'))