Thread: extract or date_part on an interval? How many e

extract or date_part on an interval? How many e

From
Bryce Nesbitt
Date:
Hmm.  Seemed so simple.  But how do I get the number of years an
interval represents?  extract is clearly the wrong way:

stage=# select 'now()-'1987-02-01' as interval,extract(year from
now()-'1987-02-01') as age;       interval          | age
--------------------------+-----
7665 days 18:05:51.660345 |   0

select EXTRACT(year FROM INTERVAL '7665 days'); gives the same result.

select EXTRACT(day FROM now()-'1987-02-01')/365 as age; seems messy.
select (now()-'1987-02-01')/365; gives extraneous junk.
Thanks!

-- 
----
Visit http://www.obviously.com/




Re: extract or date_part on an interval? How many e

From
Adrian Klaver
Date:
On Sunday 27 January 2008 6:30 pm, Bryce Nesbitt wrote:
> Hmm.  Seemed so simple.  But how do I get the number of years an
> interval represents?  extract is clearly the wrong way:
>
> stage=# select 'now()-'1987-02-01' as interval,extract(year from
> now()-'1987-02-01') as age;
>         interval          | age
> --------------------------+-----
> 7665 days 18:05:51.660345 |   0
>
> select EXTRACT(year FROM INTERVAL '7665 days'); gives the same result.
>
> select EXTRACT(day FROM now()-'1987-02-01')/365 as age; seems messy.
> select (now()-'1987-02-01')/365; gives extraneous junk.
>
>  Thanks!

SELECT age('1987-02-01'::timestamp);          age
--------------------------20 years 11 mons 26 days
(1 row)

-- 
Adrian Klaver
aklaver@comcast.net


Re: extract or date_part on an interval? How many e

From
Tom Lane
Date:
Bryce Nesbitt <bryce1@obviously.com> writes:
> Hmm.  Seemed so simple.  But how do I get the number of years an
> interval represents?  extract is clearly the wrong way:

There is nothing simple about datetime calculations, ever :-(

Let me exhibit why this particular case is not as simple as you
could wish:

regression=# select '2007-02-01'::timestamp + interval '1 year';     ?column?       
---------------------2008-02-01 00:00:00
(1 row)

regression=# select '2007-02-01'::timestamp + interval '365 days';     ?column?       
---------------------2008-02-01 00:00:00
(1 row)

regression=# select '2008-02-01'::timestamp + interval '1 year';     ?column?       
---------------------2009-02-01 00:00:00
(1 row)

regression=# select '2008-02-01'::timestamp + interval '365 days';     ?column?       
---------------------2009-01-31 00:00:00
(1 row)

That is, there isn't any fixed conversion factor between N days
and N years, so the interval datatype treats them as incommensurate.

If you're willing to settle for an approximate answer, you can
do extract(epoch from interval) and then divide by however many
seconds you want to believe are in a year.  This will give various
wrong answers in various corner cases, but I'm not sure there is
a right answer.
        regards, tom lane


Re: extract or date_part on an interval? How many e

From
Bryce Nesbitt
Date:
Sigh. Ok, I settled on:<br /><blockquote><tt>select '1987-01-29'::timestamp + interval '21 years' > now();</tt><br
/></blockquote>Which is closer to what I wanted anyway (this was all about determining who was under 21 years old). 
Thisat least should be robust over leap years.<br /><br /><br /> Tom Lane wrote:<br /><blockquote
cite="mid:16843.1201489840@sss.pgh.pa.us"type="cite"><pre wrap="">There is nothing simple about datetime calculations,
ever:-( </pre></blockquote><br /><pre class="moz-signature" cols="100">-- 
 
----
Visit <a class="moz-txt-link-freetext" href="http://www.not-so-obviously.com/">http://www.not-so-obviously.com/</a>
</pre>

Re: extract or date_part on an interval? How many e

From
Michael Glaesemann
Date:
On Jan 27, 2008, at 23:51 , Bryce Nesbitt wrote:

> Sigh. Ok, I settled on:
> select '1987-01-29'::timestamp + interval '21 years' > now();
> Which is closer to what I wanted anyway (this was all about  
> determining who was under 21 years old).  This at least should be  
> robust over leap years.

I think this should work for you for your particular case:

EXTRACT(year FROM AGE(born_on)) >= 21
 SELECT born_on, current_date, age(born_on), EXTRACT(year FROM AGE 
(born_on)) AS age_in_years, EXTRACT(year FROM age(born_on)) >= 21 as  
old_enough_to_drink FROM (SELECT CAST('1987-01-25' AS DATE) + i AS  
born_on FROM generate_series(0,5) as the(i)) foo;  born_on   |    date    |           age            | age_in_years |

old_enough_to_drink
------------+------------+--------------------------+-------------- 
+--------------------- 1987-01-25 | 2008-01-28 | 21 years 3 days          |           21 | t 1987-01-26 | 2008-01-28 |
21years 2 days          |           21 | t 1987-01-27 | 2008-01-28 | 21 years 1 day           |           21 | t
1987-01-28| 2008-01-28 | 21 years                 |           21 | t 1987-01-29 | 2008-01-28 | 20 years 11 mons 30 days
|          20 | f 1987-01-30 | 2008-01-28 | 20 years 11 mons 29 days |           20 | f
 
(6 rows)

Michael Glaesemann
grzm seespotcode net