Thread: Convert TimeStamp to Date

Convert TimeStamp to Date

From
"shuai@objectwareinc.com"
Date:
Hi all,

I am trying to convert a timestamp field to a date. ('1993-08-10
17:48:41.074' to '1993-08-10').
I used date(TIMESTAMP_FIELD), but it seemed working only for date
after year 2000 and return the previous date
for any day before year 2000. Is that a bug or I just didn't
understand the function?

I am now using to_date(TIMESTAMP_FIELD,'YYYY-MM-DD'). It works but
the performance is very poor. My query is about
2-3 times slower now.

So, what is the most efficient way to cast a timestamp field to a
date?

Thank you for your time!

LS

Re: Convert TimeStamp to Date

From
Patrick Welche
Date:
On Wed, Jul 23, 2003 at 01:36:52PM -0400, shuai@objectwareinc.com wrote:
> Hi all,
>
> I am trying to convert a timestamp field to a date. ('1993-08-10
> 17:48:41.074' to '1993-08-10').
> I used date(TIMESTAMP_FIELD), but it seemed working only for date
> after year 2000 and return the previous date
> for any day before year 2000. Is that a bug or I just didn't
> understand the function?

tree=# select date('1993-08-10 17:48:41.074');
    date
------------
 10-08-1993
(1 row)

Maybe I don't understand what you mean: that was a date before 2000, and
it seems to give the right answer..

I tend to be pedantic and use
  select cast('1993-08-10 17:48:41.074' as date)

Cheers,

Patrick

Re: Convert TimeStamp to Date

From
Ron Johnson
Date:
On Wed, 2003-07-23 at 12:48, Patrick Welche wrote:
> On Wed, Jul 23, 2003 at 01:36:52PM -0400, shuai@objectwareinc.com wrote:
> > Hi all,
> >
> > I am trying to convert a timestamp field to a date. ('1993-08-10
> > 17:48:41.074' to '1993-08-10').
> > I used date(TIMESTAMP_FIELD), but it seemed working only for date
> > after year 2000 and return the previous date
> > for any day before year 2000. Is that a bug or I just didn't
> > understand the function?
>
> tree=# select date('1993-08-10 17:48:41.074');
>     date
> ------------
>  10-08-1993
> (1 row)
>
> Maybe I don't understand what you mean: that was a date before 2000, and
> it seems to give the right answer..
>
> I tend to be pedantic and use
>   select cast('1993-08-10 17:48:41.074' as date)

Works for me, too.  PG 7.3.3 on Linux 2.4.20.

template1=# create table t (f1 timestamp);
CREATE TABLE
template1=# insert into t values ('1993-08-10 17:48:41');
INSERT 16980 1
template1=# select * from t;
         f1
---------------------
 1993-08-10 17:48:41
(1 row)

template1=# select f1, date(f1), f1::date, cast(f1 as date) from t;
         f1          |    date    |     f1     |     f1
---------------------+------------+------------+------------
 1993-08-10 17:48:41 | 1993-08-11 | 1993-08-11 | 1993-08-11
(1 row)

--
+-----------------------------------------------------------------+
| Ron Johnson, Jr.        Home: ron.l.johnson@cox.net             |
| Jefferson, LA  USA                                              |
|                                                                 |
| "I'm not a vegetarian because I love animals, I'm a vegetarian  |
|  because I hate vegetables!"                                    |
|    unknown                                                      |
+-----------------------------------------------------------------+



Re: Convert TimeStamp to Date

From
"Claudio Lapidus"
Date:
> template1=# insert into t values ('1993-08-10 17:48:41');
> INSERT 16980 1
So we are talking about August 10th, right?

> template1=# select f1, date(f1), f1::date, cast(f1 as date) from t;
>          f1          |    date    |     f1     |     f1
> ---------------------+------------+------------+------------
>  1993-08-10 17:48:41 | 1993-08-11 | 1993-08-11 | 1993-08-11
> (1 row)
Here all casts give Aug. 11th, same as on my 7.3.2 (tested right now). This
is one day *more* than expected, not 'the previous date' as the original
poster said. Perhaps some sort of rounding here?

cl.

Re: Convert TimeStamp to Date

From
Dmitry Tkach
Date:
Yep ... looks like it got broken in 7.3.
7.2.4 works fine, but 7.3 (and CVS tip) doesn't.

This is because in 7.2, timestamp_date () and timestamptz_date () do the
same thing -
convert the time to Julian date and then subtruct the offset for Y2K,
and both work.

In 7.3 (and 7.4) timestamptz_date () is still doing that (and select
'1999-12-31 00:00:01'::timestamptz::date still works),
*but* timestamp_date() is changed for some reason to just divide the
timestamp by the number of microseconds per day, that is obviously wrong
for the case when ts is negative (before 2000) because integer division
(unlike floor ())  truncates towards zero...

I'd send the patch... but just thought I would better be done by someone
who knows the reason why that function had changed to begin with...

Dima



Claudio Lapidus wrote:

>>template1=# insert into t values ('1993-08-10 17:48:41');
>>INSERT 16980 1
>>
>>
>So we are talking about August 10th, right?
>
>
>
>>template1=# select f1, date(f1), f1::date, cast(f1 as date) from t;
>>         f1          |    date    |     f1     |     f1
>>---------------------+------------+------------+------------
>> 1993-08-10 17:48:41 | 1993-08-11 | 1993-08-11 | 1993-08-11
>>(1 row)
>>
>>
>Here all casts give Aug. 11th, same as on my 7.3.2 (tested right now). This
>is one day *more* than expected, not 'the previous date' as the original
>poster said. Perhaps some sort of rounding here?
>
>cl.
>
>---------------------------(end of broadcast)---------------------------
>TIP 8: explain analyze is your friend
>
>



Re: Convert TimeStamp to Date

From
Ron Johnson
Date:
On Wed, 2003-07-23 at 14:28, Claudio Lapidus wrote:
> > template1=# insert into t values ('1993-08-10 17:48:41');
> > INSERT 16980 1
> So we are talking about August 10th, right?
>
> > template1=# select f1, date(f1), f1::date, cast(f1 as date) from t;
> >          f1          |    date    |     f1     |     f1
> > ---------------------+------------+------------+------------
> >  1993-08-10 17:48:41 | 1993-08-11 | 1993-08-11 | 1993-08-11
> > (1 row)
> Here all casts give Aug. 11th, same as on my 7.3.2 (tested right now). This
> is one day *more* than expected, not 'the previous date' as the original
> poster said. Perhaps some sort of rounding here?

I didn't even notice that.  I wonder what version Patrick Welche
is running?

tree=# select date('1993-08-10 17:48:41.074');
    date
------------
 10-08-1993
(1 row)

"Many eyes make all bugs shallow"

--
+-----------------------------------------------------------------+
| Ron Johnson, Jr.        Home: ron.l.johnson@cox.net             |
| Jefferson, LA  USA                                              |
|                                                                 |
| "I'm not a vegetarian because I love animals, I'm a vegetarian  |
|  because I hate vegetables!"                                    |
|    unknown                                                      |
+-----------------------------------------------------------------+



Re: Convert TimeStamp to Date

From
Dmitry Tkach
Date:
Ron Johnson wrote:

>tree=# select date('1993-08-10 17:48:41.074');
>    date
>------------
> 10-08-1993
>(1 row)
>
>
>
This *does* work on 7.3 (I suppose, because it ends up converting *text*
to date, not *timestamp*, and it is timestamp conversion, that's broken):

testdb=# select date('1993-08-10 17:48:41.074'::timestamp);
    date
------------
 1993-08-11
(1 row)


Dima



Re: Convert TimeStamp to Date

From
"shuai@objectwareinc.com"
Date:
>Yep ... looks like it got broken in >7.3.
>7.2.4 works fine, but 7.3 (and CVS tip) >doesn't.

>This is because in 7.2, timestamp_date >() and timestamptz_date ()
do the
>same thing -
>convert the time to Julian date and >then subtruct the offset for
Y2K,
>and both work.

>In 7.3 (and 7.4) timestamptz_date () is >still doing that (and
select
>'1999-12-31 >00:00:01'::timestamptz::date still >works),
>*but* timestamp_date() is changed for >some reason to just divide
the
>timestamp by the number of microseconds >per day, that is obviously
wrong
>for the case when ts is negative >(before 2000) because integer
division
>(unlike floor ())  truncates towards >zero...

Thank you and everybody else. This explains it.

But still, is there a solution other than casting a timestamp to
timestamptz and then to date? Because I major concern is
performance.(and I probably can't change to another version) Thanks.

LS

Re: [BUGS] Convert TimeStamp to Date

From
Tom Lane
Date:
Dmitry Tkach <dmitry@openratings.com> writes:
> In 7.3 (and 7.4) timestamptz_date () is still doing that (and select
> '1999-12-31 00:00:01'::timestamptz::date still works),
> *but* timestamp_date() is changed for some reason to just divide the
> timestamp by the number of microseconds per day, that is obviously wrong
> for the case when ts is negative (before 2000) because integer division
> (unlike floor ())  truncates towards zero...

Good catch.  It looks like Tom Lockhart changed this routine when he was
adding the int64-timestamp option.  He probably had a momentary brain
fade about the direction of rounding needed :-(

I've changed it back to doing things the 7.2 way in CVS tip.  This will
be in 7.3.4 unless Marc already wrapped the tarball, which I don't think
he did.

            regards, tom lane