Как преобразовать интервал, например 1 день 01:30:00, в 25:30:00?

Мне нужно добавить несколько интервалов и использовать результат в Excel.

С

sum(time.endtime-time.starttime)

возвращает интервал как «1 день 01:30:00», и этот формат разбивает мой лист Excel, я подумал, что было бы неплохо иметь вывод как «25:30:00», но не нашел способа сделать это в PostgreSQL документация.

Кто-нибудь здесь может мне помочь?


person Ole    schedule 04.12.2008    source источник


Ответы (6)


Так как нет точного решения по теме:

=> SELECT date_part('epoch', INTERVAL '1 day 01:30:00') * INTERVAL '1 second' hours;
  hours
-----------
 25:30:00
(1 row)

Источник: документация.

person neshkeev    schedule 23.06.2014
comment
Большой! Идеальное решение. - person Piotr Olaszewski; 04.02.2015

Единственное, с чем я могу прийти (помимо анализа количества дней и добавления 24 часов к часам каждый раз):

mat=> select date_part('epoch', '01 day 1:30:00'::interval);
 date_part 
-----------
     91800
(1 row)

Это даст вам количество секунд, которое может подойти для Excel.

person mat    schedule 04.12.2008
comment
Отличный материал. Мне нужен был какой-то способ взять абсолют из интервала, и первым шагом, который мне был нужен, было «приведение» интервала к секундам, и это просто помогло :) SELECT * FROM table ORDER BY abs(date_part('epoch',('2011-07-19 02:40:05' - table.time))) - person Boro; 19.12.2012

Вы можете использовать EXTRACT для преобразования интервала в секунды.

SELECT EXTRACT(EPOCH FROM INTERVAL '5 days 3 hours');
Result: 442800

Тогда вам нужно будет сделать свою собственную математику (или позволить Excel сделать это).

Обратите внимание, что «1 день» не обязательно эквивалентен «24 часам» — PostgreSQL обрабатывает такие вещи, как интервал, охватывающий переход на летнее время.

person slim    schedule 04.12.2008
comment
В (временная метка | дата | время) с часовым поясом, да, но, кхм, интервал не имеет представления о том, когда это происходит, поэтому он не имеет значения перехода на летнее время или дополнительных секунд. - person mat; 04.12.2008
comment
osm=> выберите '2008-03-29T02:00:05+0200'::timestamptz + '1 день'::interval; ?столбец? ------------------------ 2008-03-30 01:00:05+01 (1 ряд) - person mat; 04.12.2008
comment
Я не могу быть авторитетным в этом вопросе, но кажется, что Postgres хранит интервал как набор полей, а не просто целое число, которое преобразуется для отображения. Оно будет интерпретироваться как разное количество секунд в зависимости от того, где оно применяется. Лишение его контекста означает, что он должен делать предположения. - person slim; 04.12.2008

Если вы хотите, чтобы postgres обрабатывал для вас форматирование ЧЧ:ММ:СС, возьмите разницу в секундах эпохи и преобразуйте ее в интервал, масштабируемый в секундах:

SELECT SUM(EXTRACT(EPOCH FROM time.endtime) - EXTRACT(EPOCH FROM time.starttime))
         * INTERVAL '1 SECOND' AS hhmmss
person pilcrow    schedule 16.06.2011
comment
Очень тонкий. Это изменяет интервал с дней, часов, минут, секунд на секунды, после чего вы можете просто выполнить to_char(xxx, 'HH24:MI:SS'). - person sayap; 24.02.2012

В стандартном SQL вы хотите представить тип как INTERVAL HOUR TO SECOND, но у вас есть значение типа INTERVAL DAY TO SECOND. Разве вы не можете использовать CAST, чтобы получить требуемый результат? В Informix это может быть одно из следующих обозначений:

SUM(time.endtime - time.starttime)::INTERVAL HOUR(3) TO SECOND

CAST(SUM(time.endtime - time.starttime) AS INTERVAL HOUR(3) TO SECOND)

Первое, насколько мне известно, является нотацией, специфичной для Informix (или, по крайней мере, не стандартной); последнее, я полагаю, является стандартной нотацией SQL.

person Jonathan Leffler    schedule 04.12.2008

Это можно сделать, но я считаю, что единственный способ - через следующее чудовище (при условии, что имя столбца временного интервала - "ti"):

select
              to_char(floor(extract(epoch from ti)/3600),'FM00')
    || ':' || to_char(floor(cast(extract(epoch from ti) as integer) % 3600 / 60), 'FM00')
    || ':' || to_char(cast(extract(epoch from ti) as integer) % 60,'FM00')
    as hourstamp
from whatever;

Видеть? Я же говорил, что это ужасно :)

Было бы неплохо подумать, что

select to_char(ti,'HH24:MI:SS') as hourstamp from t

сработало бы, но, увы, формат HH24 не «поглощает» переполнение за пределами 24. Вышеприведенное исходит (реконструировано по памяти) из некоторого кода, который я когда-то написал. Чтобы не обидеть тех, у кого хрупкое телосложение, я сформулировал вышеприведенные махинации в виде...

person dland    schedule 08.12.2008