Получение секунд между двумя отметками времени Oracle - PullRequest
17 голосов
/ 18 октября 2010

Том Кайт предлагает использовать 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

Итак, как можно получить разницу между двумя метками времени в секундах? Спасибо!

Ответы [ 5 ]

17 голосов
/ 19 октября 2010

«Лучшая практика»

Что бы вы ни делали, оберните это в функцию, например, seconds_between (from_date, to_date) - не имеет значения, как он это делает (выберите наиболее эффективный метод) - тогда будет совершенно очевидно, что делает ваш код.

Производительность

Я проверил два метода на 11gR1 на своем ноутбуке (WinXP) с тестовым примером ниже. Кажется, вариант 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;
8 голосов
/ 09 июля 2014

Альтернатива:
Я нашел, что это работает, чтобы получить разницу в секундах, включая миллисекунды.
Это даже экономит для часовых поясов с "летним временем", в то время как метод извлечения имел бы проблему. К сожалению, разница между 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);
3 голосов
/ 18 октября 2010

Я всегда использовал второй способ, то есть сравнивал ДАТЫ (которые дают вам разницу в количестве дней с дробной частью) и умножал на коэффициент, который вы хотите дать вам количество часов, минут, секунд или что угодно.

Я думаю, что это хорошо и легко читается.

1 голос
/ 18 октября 2010

Лично я нахожу:

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

понятнее по назначению, чем ...

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

, чтобы получить разницу в секундах.

Метод Тома требуетеще несколько нажатий клавиш, но цель ясна.

0 голосов
/ 16 апреля 2014
to_number(to_char(t2, 'yyyymmddhh24missff')) - to_number(to_char(t1, 'yyyymmddhh24missff'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...