3

使用带有 linux psql 控制台和 windows pgadminIII 的 postgresql 9.1 查询:

select '2012-05-05 15:57:31-07'::timestamp with time zone - '2012-05-01 23:13:34-07'::timestamp with time zone;

将返回呈现为:

    ?column?     
-----------------
 3 days 16:43:57
(1 row)

但是,windows JDBC 驱动程序(特别是使用 jasperreport 的 ireport)将这个查询呈现为:

    ?column?     
-----------------
 0 years 0 mons 3 days 16 hours 43 mins 57.00 secs
(1 row)

我已经探索to_charpostgresql 文档,但找不到解决方案。两个问题:首先,如何使 JDBC 驱动程序以与 pqsl 相同的格式呈现间隔?

其次,我可以改为让 psql 和 JDBC 都将结果呈现为:

88:43:57  

随着时间间隔的增加,小时数一直计数到 100 秒(这是一个愚蠢的行业标准......)

4

3 回答 3

1

“首先,如何让 JDBC 驱动程序以与 pqsl 相同的格式呈现间隔?”
我认为这个问题实际上并没有很好的定义。类型的对象org.postgresql.util.PGInterval没有格式。当然,如果你在它上面调用 toString(),那么你会得到一些东西。您将获得 iReport 显示的内容。所以从某种意义上说,这是它的默认格式。但实际上它只是一堆用于表示年、月、日、小时、分钟的整数,以及表示秒的双精度数。这不是格式化的东西。

pgAdmin III 做了一些魔术来更好地格式化它。但是这个魔法并没有内置到 JDBC 驱动程序中。Szymon 的回答肯定会奏效。但是... 废话。

“其次,我能否改为让 psql 和 JDBC 都将结果呈现为:88:43:57
您可以将逻辑放入 .jrxml 而不是 Szymon 的过程。这会更好,因为......好吧......它不会真的更好。只是会有所不同。它可以让你通过在报告中计算这个来保持你的 SQL 查询不变:

$F{?column?}.getDays() * 24 + $F{?column?}.getHours()
+ ":" + $F{?column?}.getMinutes() + ":" + $F{?column?}.getSeconds()

这不是 100% 正确的。您需要根据您的要求将秒数从 double 截断(舍入?)为 int。并且要完全通用,您需要添加数月和数年,但也许您并不真正关心这些。无论如何,你可以这样做。警告间隔器。

于 2012-05-15T06:29:59.567 回答
0

我不知道你可以使用任何标准函数,但你总是可以像这样格式化它:

CREATE OR REPLACE FUNCTION format_time(t INTERVAL) 
RETURNS TEXT
LANGUAGE PLPGSQL
AS $$
DECLARE
    res TEXT;
BEGIN
    res = 24 * EXTRACT(day FROM t ) + EXTRACT(hour FROM t );
    res = res || ':';
    res = res || EXTRACT(minute FROM t);
    res = res || ':';
    res = res || EXTRACT(second FROM t);
    RETURN res;
END;
$$;

你可以像这样使用它:

SELECT format_time(
    '2012-05-05 15:57:31-07'::timestamp with time zone 
    - 
    '2012-05-01 23:13:34-07'::timestamp with time zone
);
于 2012-05-14T21:18:28.990 回答
0

我为自己做了一个功能,可以满足我的需要。我全神贯注于建议、改进和优化。

create or replace function format_hours(started timestamp with time zone, stopped timestamp with time zone)
returns text as $$
declare
        epoch_interval integer := extract(epoch from stopped - started);
        hours integer   := floor(epoch_interval/3600);
        minutes integer := floor((epoch_interval-hours*3600)/60);
        seconds integer := floor((epoch_interval-hours*3600-minutes*60));
begin
      return hours::text || ':' ||
             to_char(minutes, 'FM00') || ':' ||
             to_char(seconds, 'FM00');
end;
$$ language plpgsql;
于 2012-05-16T17:08:51.877 回答