Обсуждение: BUG #4972: RFE: convert timestamps to fractional seconds

Поиск
Список
Период
Сортировка

BUG #4972: RFE: convert timestamps to fractional seconds

От
"Richard Neill"
Дата:
The following bug has been logged online:

Bug reference:      4972
Logged by:          Richard Neill
Email address:      rn214@cam.ac.uk
PostgreSQL version: 8.3.7
Operating system:   Linux
Description:        RFE: convert timestamps to fractional seconds
Details:

Postgresql has a huge range of functions to convert things TO timestamp
format, but no way to convert back again.

For example:

* Convert a timestamp into a number of seconds since
the epoch. This can be done in an ugly way using EXTRACT epoch FROM
timestamp, but only to  integer
precision. If I want to keep the microseconds, and get a float, it's not
possible. [Also, this is such a common requirement that it should probably
have a dedicated function, such as "time()" or maybe "epoch()". In PHP, this
is done by strtotime().]

* Division of a timestamp by an interval should result in something
dimensionless.

* So, for example, to check whether two timestamps (ts1 and ts2) are less
than 2.5 seconds apart, (returning boolean), I'd like to be able to do at
least one of:

  abs(time(ts1 - ts2)) < 2.5
  #A "time" function converts timestamp to
  #sec.us since epoch)

  abs(cast (ts1 - ts2) as double)  < 2.5
  #cast to double, might have to implicitly divide
  #by the unit of "1 second"

  (ts1 - ts2) / INTERVAL '1 second'  < 2.5
  #Divide 2 dimensioned quantities to get
  #a dimensionless one.


Currently, it's necessary to do something really really long-winded, eg:

(ts1 - ts2 >= 0 AND ts1 - ts2 < interval '2.5 seconds') OR (ts2 - ts1 >= 0
AND ts2 - ts1 < interval '2.5 seconds')


BTW,The abs() function doesn't work on an INTERVAL, though there is no
reason why it shouldn't.

Thanks - Richard

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Tom Lane
Дата:
"Richard Neill" <rn214@cam.ac.uk> writes:
> * Convert a timestamp into a number of seconds since
> the epoch. This can be done in an ugly way using EXTRACT epoch FROM
> timestamp, but only to  integer precision.

Uh, nonsense.

regression=# select extract(epoch from now());
    date_part
------------------
 1249884955.29859
(1 row)

It might've been like that back around 7.1, but not in any currently
supported version.

> * Division of a timestamp by an interval should result in something
> dimensionless.

This isn't a particularly sane thing to think about, because intervals
aren't single numbers.

            regards, tom lane

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Peter Eisentraut
Дата:
On Monday 10 August 2009 03:41:06 Richard Neill wrote:
> * Division of a timestamp by an interval should result in something
> dimensionless.

What would be the semantics of this?  What's today divided by 2 hours?

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Francisco Olarte Sanz
Дата:
On Monday 10 August 2009, Richard Neill wrote:
> * So, for example, to check whether two timestamps (ts1 and ts2) are less
> than 2.5 seconds apart, (returning boolean), I'd like to be able to do at
> least one of:
>
>   abs(time(ts1 - ts2)) < 2.5
>   #A "time" function converts timestamp to
>   #sec.us since epoch)
>
>   abs(cast (ts1 - ts2) as double)  < 2.5
>   #cast to double, might have to implicitly divide
>   #by the unit of "1 second"
>
>   (ts1 - ts2) / INTERVAL '1 second'  < 2.5
>   #Divide 2 dimensioned quantities to get
>   #a dimensionless one.

What is wrong with (ts1-ts2) between i1 and i2:

cdrs=> select version();
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 8.2.4 on i686-pc-linux-gnu, compiled by GCC i686-pc-linux-gnu-gcc
(GCC) 4.1.2 (Gentoo 4.1.2)


cdrs=> select ('today 01:23:45'::timestamp - 'today 01:23:42.3'::timestamp)
between '-2.5 seconds'::interval and '2.5 seconds'::interval;
 ?column?
----------
 f
(1 row)

cdrs=> select ('today 01:23:45'::timestamp - 'today 01:23:42.7'::timestamp)
between '-2.5 seconds'::interval and '2.5 seconds'::interval;
 ?column?
----------
 t
(1 row)

cdrs=> select ('today 01:23:45'::timestamp - 'today 01:23:47.3'::timestamp)
between '-2.5 seconds'::interval and '2.5 seconds'::interval;
 ?column?
----------
 t
(1 row)

cdrs=> select ('today 01:23:45'::timestamp - 'today 01:23:47.7'::timestamp)
between '-2.5 seconds'::interval and '2.5 seconds'::interval;
 ?column?
----------
 f
(1 row)

> Currently, it's necessary to do something really really long-winded, eg:
> (ts1 - ts2 >= 0 AND ts1 - ts2 < interval '2.5 seconds') OR (ts2 - ts1 >= 0
> AND ts2 - ts1 < interval '2.5 seconds')

Not really, as you pointed out abs(interval) doesn't work for me, but a simple
between is easier than this, and intervals seem to support sign properly.

F.O.S.

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Richard Neill
Дата:
Dear Peter and Tom,

Thanks for your help. Sorry for posting an incorrect bug report. I hope
there are still a few useful parts...


Tom Lane wrote:
> "Richard Neill" <rn214@cam.ac.uk> writes:
>> * Convert a timestamp into a number of seconds since
>> the epoch. This can be done in an ugly way using EXTRACT epoch FROM
>> timestamp, but only to  integer precision.
>
> Uh, nonsense.
>
> regression=# select extract(epoch from now());
>     date_part
> ------------------
>  1249884955.29859
> (1 row)
>

You're quite right - I stand corrected. I'm sorry - my experiment was
clearly faulty - and when I checked the documentation, I read:


    SELECT EXTRACT(EPOCH FROM TIMESTAMP WITH TIME ZONE '2001-02-16
    20:38:40-08');
    Result: 982384720

and saw that the result was an integer. (which is correct, but it threw
me off the scent).


Aside: I still contend that this isn't a very obvious way to do it,
being hard to find in the documentation, and slightly inconsistent
because every other EXTRACT option pulls out some fraction of the field.
(eg Extract month gives the current month number, rather than the number
of whole months elapsed since the epoch). Also, a shorthand function
name for this would be helpful.



There are two places where I think the documentation on this page
http://www.postgresql.org/docs/8.3/static/functions-datetime.html
could be improved:

  (a) Table 9-26. Date/Time Functions doesn't contain ANY summary for how
      to get the seconds since the epoch. An initial look at EXTRACT
      would make it appear irrelevant.

  (b) Nowhere on the page is there a full example for getting
      seconds+microseconds since the epoch



>
>> * Division of a timestamp by an interval should result in something
>> dimensionless.
>
> This isn't a particularly sane thing to think about, because intervals
> aren't single numbers.
>


Peter Eisentraut wrote:
 > On Monday 10 August 2009 03:41:06 Richard Neill wrote:
 >> * Division of a timestamp by an interval should result in something
 >> dimensionless.
 >
 > What would be the semantics of this?  What's today divided by 2 hours?
 >


I see your point. But on the other hand, it's very common to talk about
    "distance (in metres) = 300"
or "50 seconds /  seconds   = 50"

What I think I meant was dividing a differential timestamp by an
interval. In this case, both should be unambiguously expressed in
seconds, and the result will be dimensionless.


For example:
        select interval '3 weeks' / interval '1 week';
will fail, yet

    select extract (epoch  from interval '3 weeks') / extract (epoch
    from interval '1 week');
gives the correct answer of 3.




Do you agree that an explicit cast of a timestamp to a double should work?

Do you agree that abs() should be able to operate on an interval?
      select abs( interval '-1 week');


Thanks for your help,

Richard

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Robert Haas
Дата:
On Mon, Aug 10, 2009 at 8:52 AM, Richard Neill<rn214@cam.ac.uk> wrote:
> What I think I meant was dividing a differential timestamp by an interval.
> In this case, both should be unambiguously expressed in seconds, and the
> result will be dimensionless.

And what will you get when you divide 1 month by 1 day?

...Robert

Re: BUG #4972: RFE: convert timestamps to fractional seconds

От
Tom Lane
Дата:
Richard Neill <rn214@cam.ac.uk> writes:
>   (b) Nowhere on the page is there a full example for getting
>       seconds+microseconds since the epoch

Yeah, we could change that example to include a fractional part in the
timestamp to make this clearer.

> What I think I meant was dividing a differential timestamp by an
> interval. In this case, both should be unambiguously expressed in
> seconds, and the result will be dimensionless.

What you're missing is that intervals are not single numbers, and
are not simply numbers of seconds.

> Do you agree that an explicit cast of a timestamp to a double should work?

Doesn't seem like a particularly good idea.  You're free to add such
a cast to your own DBs, of course.

> Do you agree that abs() should be able to operate on an interval?
>       select abs( interval '-1 week');

It's not as easy as that, because (once again) intervals aren't single
numbers.  For example, what should become of
    abs(interval '-1 month +1 day')
The negative of this would be '1 month -1 day'.  It's not real clear to
me whether abs() should give that or '1 month 1 day', ie, make all the
fields positive independently.

            regards, tom lane