如何在两个Oracle时间戳之间获得秒数?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

extract( day from (x-y) )*24*60*60+
extract( hour from (x-y) )*60*60+
...

例如,这似乎比较难以阅读并且比此慢。

( CAST( x AS DATE ) - CAST( y AS DATE ) ) * 86400

那么,在几秒钟内获得两个时间戳之间差异的方法是什么?

提问于
用户回答回答于

替代方案: 我发现这个工作以及在几秒钟内得到差异包括毫秒。 它甚至可以节省“夏令时”的时区,而提取方法会产生问题。不幸的是,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);
用户回答回答于

“最佳实践”

无论你做什么,都将它包装在一个函数中,例如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;

扫码关注云+社区