Oracle конвертирует секунды в часы:минуты:секунды

У меня есть требование отображать доступное время пользователя в формате Часы:Минуты:Секунды из заданного значения общего количества секунд. Цените, если вы знаете функцию ORACLE, чтобы сделать то же самое. Я использую Оракл.

Спасибо за ваше время.


person user1430989    schedule 12.06.2012    source источник


Ответы (12)


Если вы просто хотите преобразовать заданное количество секунд в формат HH:MI:SS, это должно сделать это

SELECT 
    TO_CHAR(TRUNC(x/3600),'FM9900') || ':' ||
    TO_CHAR(TRUNC(MOD(x,3600)/60),'FM00') || ':' ||
    TO_CHAR(MOD(x,60),'FM00')
FROM DUAL

где x — количество секунд.

person Mike    schedule 12.06.2012
comment
Это хорошо работает. Но если часы › 99 часов, то он работает неправильно - person user1430989; 13.06.2012
comment
См. мое редактирование с использованием TO_CHAR вместо LPAD. Теперь он должен работать до 9999 часов. Если вам нужно больше, вы можете добавить дополнительные 9 к строке формата в первой функции TO_CHAR. - person Mike; 13.06.2012
comment
Это неправильно для следующего случая: SELECT TO_CHAR(TRUNC(76014000/3600),'FM999999900') || 'Часы' || TO_CHAR(TRUNC(MOD(76014000,3600)/60),'FM00') || 'МИН' ОТ ДВОЙНОЙ; - person Nishanthi Grashia; 15.04.2014
comment
@Nisha - выполнение вашего запроса дало мне 21115 часов 00 минут ... мне кажется, это правильно. - person Mike; 17.04.2014
comment
@Mike: Ожидаемый ответ был 21.115 часов. Но запрос вернул 21115 часов. Только сейчас понял, что использую миллисекунды. Запрос работает правильно. Мне нужно будет преобразовать миллисекунды в секунды и заменить их вместо X, и это сработает... Спасибо!! - person Nishanthi Grashia; 17.04.2014
comment
Отличный ответ @Mike! Есть ли способ показать миллисекунды? - person Guilherme Matheus; 27.05.2020
comment
@GuilhermeMatheus Если вы имеете в виду, что ваше значение «x» указано в миллисекундах, вы можете использовать что-то вроде: SELECT TO_CHAR(TRUNC(x/1000/3600),'FM9900') || ':' || TO_CHAR(TRUNC(MOD(x/1000,3600)/60),'FM00') || ':' || TO_CHAR(MOD(x/1000,60),'FM00') || '.' || TO_CHAR(MOD(x,1000),'FM000') ОТ ДВОЙНОГО - person Mike; 14.09.2020

Попробуй это. Очень простой и удобный в использовании

select to_char(to_date(10000,'sssss'),'hh24:mi:ss') from dual;
person vogash    schedule 23.10.2012
comment
Мне это нравится больше, чем мой ответ, но он не работает более 86399 секунд (1 день). - person Mike; 05.12.2013
comment
идеальное решение - person TroniPM; 12.06.2020

Следующий код менее сложен и дает тот же результат. Обратите внимание, что «X» — это количество секунд, которое необходимо преобразовать в часы.

В Oracle используйте:

SELECT TO_CHAR (TRUNC (SYSDATE) + NUMTODSINTERVAL (X, 'second'),
                'hh24:mi:ss'
               ) hr
  FROM DUAL;

В SqlServer используйте:

SELECT CONVERT(varchar, DATEADD(s, X, 0), 108);
person Community    schedule 18.06.2015
comment
Что, если я хочу добавить «дни»? - person wonsuc; 28.08.2020

Если у вас есть переменная, содержащая f.e. 1 минута (в секундах), вы можете добавить ее в системную метку, а затем использовать to_char, чтобы выбрать из нее разные части времени.

select to_char(systimestamp+60/(24*60*60), 'yyyy.mm.dd HH24:mi:ss') from dual
person Bjarni Sævarsson    schedule 12.06.2012
comment
Я попробовал это. Это плохо работает. потому что давайте подумаем о секундах, которые составляют более 86400 секунд (более 24 часов в день). Пример: 86410 секунд, т.е. 1 день 10 секунд, что равно: 24:00:10 в формате чч:мм:сс. Но, как указано выше, это просто дает вам: значение 00:00:10, что неверно. ... - person user1430989; 13.06.2012
comment
Я пробовал что-то вроде этого. SELECT TO_CHAR (TRUNC (SYSDATE) + NUMTODSINTERVAL (82400, 'секунда'), 'hh24:mi:ss' ) hr FROM DUAL; - person user1430989; 13.06.2012
comment
Мое решение действительно работает. Вы получаете 00:00:10, потому что используете TRUNC(SYSDATE). Замените TRUNC (SYSDATE) на systimestamp и повторите попытку. - person Bjarni Sævarsson; 13.06.2012
comment
Кстати, sysdate с точностью до секунды, systimestamp с точностью до миллисекунды. - person Bjarni Sævarsson; 13.06.2012

К сожалению, нет... Однако есть простой трюк, если это будет меньше 24 часов.

Oracle предполагает, что к дате добавляется число в днях. Преобразуйте количество секунд в дни. Добавьте текущий день, затем используйте функцию to_date, чтобы взять только те части, которые вас интересуют. Предполагая, что у вас есть x секунд:

select to_char(sysdate + (x / ( 60 * 60 * 24 ) ), 'HH24:MI:SS')
  from dual

Это не сработает, если есть более 24 часов, хотя вы можете снова удалить текущие данные и получить разницу в днях, часах, минутах и ​​секундах.

Если вам нужно что-то вроде: 51:10:05, то есть 51 час, 10 минут и 5 секунд, вам придется использовать trunc.

Еще раз предполагая, что у вас есть x секунд...

  • Количество часов trunc(x / 60 / 60)
  • Количество минут trunc((x - ( trunc(x / 60 / 60) * 60 * 60 )) / 60)
  • Таким образом, количество секунд равно x - hours * 60 * 60 - minutes * 60

Оставив вам:

with hrs as (
  select x, trunc(x / 60 / 60) as h
    from dual
         )
 , mins as (
  select x, h, trunc((x - h * 60 * 60) / 60) as m
    from hrs
         )
select h, m, x - (h * 60 * 60) - (m * 60)
  from mins

Для демонстрации я настроил SQL Fiddle.

person Ben    schedule 12.06.2012
comment
Добавить одну секунду намного проще: sysdate + interval '1' second - person a_horse_with_no_name; 13.06.2012
comment
@a_horse_with_no_name, честно говоря, это на самом деле длиннее и не решает второй вопрос, но выглядит чище! - person Ben; 13.06.2012
comment
Возможно, вы имели в виду trunc(sysdate) + (x / (60 * 60 * 24)) в первом фрагменте выше? - person Bob Jarvis - Reinstate Monica; 13.06.2012
comment
Спасибо, @bob, действительно! - person Ben; 13.06.2012

Ниже приведен еще один способ (tm) — он по-прежнему требует небольшого расчета, но дает пример использования EXTRACT для извлечения отдельных полей из INTERVAL:

DECLARE 
  SUBTYPE BIG_INTERVAL IS INTERVAL DAY(9) TO SECOND;

  i        BIG_INTERVAL;
  nSeconds NUMBER := 86400000;

  FUNCTION INTERVAL_TO_HMS_STRING(inv IN BIG_INTERVAL)
    RETURN VARCHAR2
  IS
    nHours    NUMBER;
    nMinutes  NUMBER;
    nSeconds  NUMBER;
    strHour_format  VARCHAR2(10) := '09';
    workInv   INTERVAL DAY(9) TO SECOND(9);
  BEGIN
    nHours := EXTRACT(HOUR FROM inv) + (EXTRACT(DAY FROM inv) * 24);
    strHour_format := TRIM(RPAD(' ', LENGTH(TRIM(TO_CHAR(ABS(nHours)))), '0') || '9');

    nMinutes := ABS(EXTRACT(MINUTE FROM inv));
    nSeconds := ABS(EXTRACT(SECOND FROM inv));

    RETURN TRIM(TO_CHAR(nHours, strHour_format)) || ':' ||
           TRIM(TO_CHAR(nMInutes, '09')) || ':' ||
           TRIM(TO_CHAR(nSeconds, '09'));
  END INTERVAL_TO_HMS_STRING;

BEGIN
  i := NUMTODSINTERVAL(nSeconds, 'SECOND');

  DBMS_OUTPUT.PUT_LINE('i (fields) = ' || INTERVAL_TO_HMS_STRING(i));
END;

Код, который извлекает поля и т. д., по-прежнему должен содержать вычисление для преобразования поля DAY в эквивалентные часы, и он не самый красивый, но аккуратно завернутый в процедуру, которую не так уж плохо использовать.

Делитесь и наслаждайтесь.

person Bob Jarvis - Reinstate Monica    schedule 13.06.2012

Предполагая, что ваше время называется st.etime ниже и хранится в секундах, вот что я использую. Это обрабатывает время, когда секунды превышают 86399 секунд (то есть 23:59:59).

случай, когда st.etime > 86399, тогда to_char(to_date(st.etime - 86400,'sssss'),'HH24:MI:SS') else to_char(to_date(st.etime,'sssss'),'HH24:MI: СС') конец readable_time

person Jonathan Wade    schedule 18.09.2014

Что касается комментария к ответу vogash, я понимаю, что вам нужно что-то вроде счетчика времени, потому что у вас может быть больше 24 часов. Для этого вы можете сделать следующее:

select to_char(trunc(xxx/3600)) || to_char(to_date(mod(xxx, 86400),'sssss'),':mi:ss') as time
from dual;

xxx — это ваше количество секунд.

Первая часть накапливает часы, а вторая часть вычисляет оставшиеся минуты и секунды. Например, имея 150023 seconds, вы получите 41:40:23.

Но если вы всегда хотите иметь hh24:mi:ss, даже если у вас есть более 86000 seconds (1 день), вы можете сделать:

select to_char(to_date(mod(xxx, 86400),'sssss'),'hh24:mi:ss') as time 
from dual;

xxx – ваше количество секунд.

Например, при наличии 86402 seconds время будет сброшено на 00:00:02.

person Scott Baxter    schedule 06.02.2015

Моя версия. Показать время безотказной работы БД Oracle в формате ДДд ЧЧч ММм СС

select to_char(trunc((((86400*x)/60)/60)/24)) || 'd ' ||
   to_char(trunc(((86400*x)/60)/60)-24*(trunc((((86400*x)/60)/60)/24)), 'FM00') || 'h ' ||
   to_char(trunc((86400*x)/60)-60*(trunc(((86400*x)/60)/60)), 'FM00') || 'm ' ||
   to_char(trunc(86400*x)-60*(trunc((86400*x)/60)), 'FM00') || 's' "UPTIME"
 from (select (sysdate - t.startup_time) x from V$INSTANCE t);

идея из Арифметика даты/времени с Oracle 9/10

person Vlad    schedule 25.06.2015

Преобразование минут в формат час:мин:сек

SELECT 
   TO_CHAR(TRUNC((MINUTES * 60) / 3600), 'FM9900') || ':' ||
   TO_CHAR(TRUNC(MOD((MINUTES * 60), 3600) / 60), 'FM00') || ':' ||
   TO_CHAR(MOD((MINUTES * 60), 60), 'FM00') AS MIN_TO_HOUR FROM DUAL
person Andrey Hideki Nakano    schedule 29.02.2016

Для более чем 24 часов вы можете включить дни с помощью следующего запроса. Возвращаемый формат: days:hh24:mi:ss

Запрос:
select trunc(trunc(sysdate) + numtodsinterval(9999999, 'second')) - trunc(sysdate) || ':' || to_char(trunc(sysdate) + numtodsinterval(9999999, 'second'), 'hh24:mi:ss') from dual;

Вывод:
115:17:46:39

person Jared    schedule 16.12.2016

Вам следует посетить этот сайт. Раздел TO_TIMESTAMP может быть вам полезен!

Синтаксис:

TO_TIMESTAMP ( string , [ format_mask ] [ 'nlsparam' ] )

person James    schedule 12.06.2012