Thread: Duda sobre como imprimir un campo INTERVAL

Duda sobre como imprimir un campo INTERVAL

From
Alejandro Baeza Rangel
Date:
Buenas tardes, tengo esta tabla 
image.png
como puedo en un report, representar la columna tiempo
ya que le pongo directo un print y me sale:
image.png

alguna sugerencia?
Attachment

Re: Duda sobre como imprimir un campo INTERVAL

From
Ken Tanzer
Date:
On Thu, Nov 17, 2022 at 2:30 PM Alejandro Baeza Rangel <jlabaezarangel@gmail.com> wrote:
Buenas tardes, tengo esta tabla 
image.png
como puedo en un report, representar la columna tiempo
ya que le pongo directo un print y me sale:
image.png

alguna sugerencia?

As a starting point, I would use something like:

to_char(fecha_f - fecha_i,'HH24:MM:ss')

But it's not clear what you're wanting for intervals longer than 24 hours.  In your sample output, only the last line fits that case, but the interval column is repeated from the previous line.  Since the interval has 45 hours, are you wanting to see 45 or 21 in the output?

WITH dates AS (
        SELECT
                '2022-11-15 12:40:00'::timestamp AS fecha_i,
                '2022-11-17 10:20:00'::timestamp AS fecha_j
)
SELECT
        *,
        fecha_j-fecha_i AS interval,
        to_char(fecha_j-fecha_i,'HH24:MI:SS')
FROM dates;
       fecha_i       |       fecha_j       |    interval    | to_char  
---------------------+---------------------+----------------+----------
 2022-11-15 12:40:00 | 2022-11-17 10:20:00 | 1 day 21:40:00 | 21:40:00
(1 row)



And then in a related mystery I hope someone can answer, I would have expected the HH24 to report 45 not 21 here, based on this comment in the documentation:

  • to_char(interval) formats HH and HH12 as shown on a 12-hour clock, i.e., zero hours and 36 hours output as 12, while HH24 outputs the full hour value, which can exceed 23 for intervals.


But it clearly doesn't, at least on my version 9.6.  Fair enough I suppose, even if I don't fully understand it.  But what really confuses me is the example below.  How can these two intervals be equal and still yield different output in the to_char function?  And as a practical matter, and for the OPs question, how can you convert from one to the other of these "equal" values?

WITH inters AS (
    SELECT
        '1 day 2 hours'::interval AS i1,
        '26 hours'::interval AS i2
)
SELECT
    *,
    to_char(i1,'HH24:MM:SS') AS i1_char,
    to_char(i2,'HH24:MM:SS') AS i2_char,
    i1=i2 AS "Equal?"
FROM inters;


       i1       |    i2    | i1_char  | i2_char  | Equal?
----------------+----------+----------+----------+--------
 1 day 02:00:00 | 26:00:00 | 02:00:00 | 26:00:00 | t


Cheers,
Ken






--
AGENCY Software  
A Free Software data system
By and for non-profits
(253) 245-3801

learn more about AGENCY or
follow the discussion.
Attachment

Re: Duda sobre como imprimir un campo INTERVAL

From
Alban Hertroys
Date:
> On 19 Nov 2022, at 4:58, Ken Tanzer <ken.tanzer@gmail.com> wrote:
>
> On Thu, Nov 17, 2022 at 2:30 PM Alejandro Baeza Rangel <jlabaezarangel@gmail.com> wrote:

(…)

> don't fully understand it.  But what really confuses me is the example below.  How can these two intervals be equal
andstill yield different output in the to_char function?  And as a practical matter, and for the OPs question, how can
youconvert from one to the other of these "equal" values? 
>
> WITH inters AS (
>     SELECT
>         '1 day 2 hours'::interval AS i1,
>         '26 hours'::interval AS i2
> )
> SELECT
>     *,
>     to_char(i1,'HH24:MM:SS') AS i1_char,
>     to_char(i2,'HH24:MM:SS') AS i2_char,
>     i1=i2 AS "Equal?"
> FROM inters;
>
>        i1       |    i2    | i1_char  | i2_char  | Equal?
> ----------------+----------+----------+----------+--------
>  1 day 02:00:00 | 26:00:00 | 02:00:00 | 26:00:00 | t
>
> Cheers,
> Ken

Those intervals are not identical. I think the reasoning is that due to DST changes, ‘1 day 2 hours’ is more specific
thanits conversion to ’26 hours’ (or 25 or 27 at DST change). 
And since you’re not converting the number of days in to_char, that information gets lost.

That problem doesn’t seem to arise in the OP’s question (as far as I understand his question), he does have dates to
basethe intervals on. However, converting the differences in dates to intervals decouples the difference from the dates
(theintervals could, for example, subsequently be added to an entirely different date) and he ends up in the same boat. 

It would seem that the way to do this is to convert the difference to (seconds since) epoch and do the math to convert
thatto a character string yourself. 

See for example:
https://stackoverflow.com/questions/341384/how-to-convert-an-interval-like-1-day-013000-into-253000

That seems unnecessarily complicated, perhaps there is/could be a more convenient method? I’m sort of thinking of a
"relativetimestamp offset" type, that tracks an exact difference relative to a given timestamp? 

Alban Hertroys
--
There is always an exception to always.







Re: Duda sobre como imprimir un campo INTERVAL

From
Ken Tanzer
Date:


On Sat, Nov 19, 2022 at 2:39 AM Alban Hertroys <haramrae@gmail.com> wrote:


> don't fully understand it.  But what really confuses me is the example below.  How can these two intervals be equal and still yield different output in the to_char function?  And as a practical matter, and for the OPs question, how can you convert from one to the other of these "equal" values?
>
> WITH inters AS (
>     SELECT
>         '1 day 2 hours'::interval AS i1,
>         '26 hours'::interval AS i2
> )
> SELECT
>     *,
>     to_char(i1,'HH24:MM:SS') AS i1_char,
>     to_char(i2,'HH24:MM:SS') AS i2_char,
>     i1=i2 AS "Equal?"
> FROM inters;
>
>        i1       |    i2    | i1_char  | i2_char  | Equal?
> ----------------+----------+----------+----------+--------
>  1 day 02:00:00 | 26:00:00 | 02:00:00 | 26:00:00 | t
>

Those intervals are not identical. I think the reasoning is that due to DST changes, ‘1 day 2 hours’ is more specific than its conversion to ’26 hours’ (or 25 or 27 at DST change).

Thanks.  I could understand that they're not identical.   But then what's going on where Postgres evaluates them as equal?  (i1=i2 above.)  Are the two intervals getting cast or converted to something else before they are compared, with whatever makes them non-identical getting lost in the conversion?

Cheers,
Ken
--
AGENCY Software  
A Free Software data system
By and for non-profits
(253) 245-3801

learn more about AGENCY or
follow the discussion.

Re: Duda sobre como imprimir un campo INTERVAL

From
Tom Lane
Date:
Ken Tanzer <ken.tanzer@gmail.com> writes:
> Thanks.  I could understand that they're not identical.   But then what's
> going on where Postgres evaluates them as equal?  (i1=i2 above.)  Are the
> two intervals getting cast or converted to something else before they are
> compared, with whatever makes them non-identical getting lost in the
> conversion?

Hmm ... the code is pretty clear about what it thinks it's doing,
but I'm not sure if this info exists anywhere in the user-facing docs:

 * Interval comparison is based on converting interval values to a linear
 * representation expressed in the units of the time field (microseconds,
 * in the case of integer timestamps) with days assumed to be always 24 hours
 * and months assumed to be always 30 days.

So once '1 day 2 hours' and '26 hours' are flattened into this linear
representation, they are indeed "equal".  There's precedent elsewhere
for values that are "equal" but not identical, so it's not a bug,
even if it's not the semantics you'd want for some particular use-case.

I think the main factor behind having done it this way is that we need
a linear sort order if we want to support btree indexes or ORDER BY
on intervals.

You can use justify_hours() to get from '26 hours' to '1 day 2 hours'.
I'm not sure if there's a compact way to go the other direction,
though you could always use extract() to get the components and
sum them up.

            regards, tom lane