2012-05-14 77 views
3

使用PostgreSQL 9.1与Linux psql的控制台和窗户pgadminIII查询:JDBC VS PSQL间隔呈现差异

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) 

然而,窗户JDBC驱动器(具体地使用jasperreport的ireport)呈现相同的查询为:

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

我探索过to_charpostgresql documentation,但无法找到解决方案。两个问题:首先,如何使JDBC驱动程序以与pqsl相同的格式显示间隔?

其次,可我反而使双方的psql和JDBC渲染结果为:

88:43:57 

哪里小时继续计数到100秒为间隔的增长(其一个愚蠢的行业标准......)

+0

你可以运行查询:“秀LC_TIME;”使用两个客户并向我们展示结果? –

+0

@SzymonGuz所有结果如下:'en_US.UTF-8'按预期。 – Justin

回答

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

是的...我希望避免这种情况。期望JDBC驱动程序呈现与psql相同的结果似乎是一件合理的事情,但我想你永远无法确定使用java。 – Justin

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%正确的。您需要截断(round?)从double到int的秒数以满足您的需求。而要完全通用,你需要在数月和数年内添加,但也许你并不真正关心这些。无论如何,你可能这样做。警告间隔。

+0

我喜欢.jrxml版本......但它是否可修改以包含跨月的间隔?或者是我最好的选择就是去提取('epoch',...)'和整数数学版本的东西? – Justin

+0

'interval'和'month'之间的一个有趣的交互/冲突。在我看来,一旦间隔包含超过零个月,那么你已经在几天/小时/分钟/秒的时间内失去了精确度。我不确定。但我会使用纪元时间,并使用整数数学,如你所建议的。 – mdahlman

+0

看到我的功能如下。 – Justin

0

当您将列间隔转换为文本时,它应该出现在jasper报告的sql查询结果中。

关于第一个问题,下面::text使用应解决的问题

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