2010-10-18 16 views
16

Tom Kyte suggests a utilizar EXTRACT para obtener la diferencia:segundos Obtención entre dos Oracle marcas de tiempo

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

Ésta parece ser más difícil de leer y más lento que esto, por ejemplo:

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

Entonces, ¿cuál es la manera de obtener la diferencia entre dos marcas de tiempo en segundos? ¡Gracias!

+5

Personalmente prefiero 24 * 60 * 60 a 86400. Incluso un no-técnico reconocería 24 como horas en un día y calcula que los años 60 se relacionan con minutos y segundos. –

+0

@Gary: ¡Eso es definitivamente cierto, gracias! –

+0

Tenga en cuenta que los resultados no son idénticos (vea mi comentario a continuación) –

Respuesta

3

Siempre he usado la segunda manera, es decir, comparo los DATE (que le da el número de días de diferencia, con una parte fraccionaria), y multiplicar por el factor que desea darle el número de horas, minutos, segundos, o lo que sea.

Creo que es bueno y fácil de leer.

1

Personalmente, me parece:

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

más claro en el propósito de ...

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

para obtener la diferencia en cuestión de segundos.

El método de Tom requiere unas pocas teclas más, pero la intención es clara.

14

"Mejor Práctica"

lo que haga, lo envuelve en una función, por ejemplo, seconds_between (from_date, to_date) - no importa cómo lo haga (elija el método más eficiente) - entonces será perfectamente obvio lo que su código está haciendo.

Rendimiento

He probado los dos métodos en 11gR1 en mi portátil (WinXP) con el caso de prueba a continuación. Parece que la opción CAST es la más rápida. (T1 es la línea de base, t2 utiliza el método de extract, t3 utiliza el método cast)

t1 (nothing) 3 
t2 (extract) 338 
t3 (cast) 101 

t1 (nothing) 3 
t2 (extract) 336 
t3 (cast) 100 

script de prueba

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; 
+0

Si bien este es un punto importante ('+ 1'), en realidad estoy buscando el método más eficiente del que me hablas :) –

+0

Puede que no haya tanta diferencia; pruébalo (p. Ej. Ejecuta cada uno miles de veces con varios entradas) y ver. –

+0

@Peter: allí tienes :) espero que ayude –

-3
to_number(to_char(t2, 'yyyymmddhh24missff')) - to_number(to_char(t1, 'yyyymmddhh24missff')) 
+0

Esto dará como resultado una diferencia de 41 segundos entre '00: 00: 59' y' 00: 01: 00'. –

7

alternativa:
he encontrado que esto funcione como bien para obtener la diferencia en segundos, incluidos milisegundos.
Es incluso ahorrar para las zonas horarias con "horario de verano", mientras que el método de extracción tendría un problema. Desafortunadamente, la diferencia entre t1 y t2 está limitada para que el resultado sea correcto. El formato de fecha y hora de publicación no es una opción porque se pierden las fracciones de segundos.

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); 
+0

¡Este es un gran truco! Envuelve eso en una ronda(), y ya estás listo. – DBK

Cuestiones relacionadas