Thread: inverse of "day of year"

inverse of "day of year"

From
Martin Marques
Date:
Is there a function that would give me the date for a given day of year?

Something like the inverse of "EXTRACT(doy FROM date)"?

-- 09:04:02 up 10 days, 13:35,  4 users,  load average: 0.42, 0.29, 0.33
-----------------------------------------------------------------
Martín Marqués        | select 'mmarques' || '@' || 'unl.edu.ar'
Centro de Telematica  |  DBA, Programador, Administrador            Universidad Nacional                 del Litoral
-----------------------------------------------------------------



Re: inverse of "day of year"

From
Robert Creager
Date:
When grilled further on (Fri, 19 Mar 2004 09:06:17 -0300),
Martin Marques <martin@bugs.unl.edu.ar> confessed:

> Is there a function that would give me the date for a given day of year?
> 
> Something like the inverse of "EXTRACT(doy FROM date)"?
> 

Something like:

select date_trunc( 'year', now() ) + (extract( doy from now() ) - 1) *
'1day'::interval;

Later,
Rob

-- 06:46:54 up 8 days,  9:58,  2 users,  load average: 2.00, 2.11, 2.09
Linux 2.4.21-0.13_test #60 SMP Sun Dec 7 17:00:02 MST 2003

Re: inverse of "day of year"

From
Tom Lane
Date:
Robert Creager <Robert_Creager@LogicalChaos.org> writes:
> Martin Marques <martin@bugs.unl.edu.ar> confessed:
>> Is there a function that would give me the date for a given day of year?

> Something like:

> select date_trunc( 'year', now() ) + (extract( doy from now() ) - 1) *
> '1day'::interval;

timestamp + interval arithmetic is likely to give you problems at
daylight savings boundaries, since '1day' will be taken as '24hours'.
A more reliable way to get (what I assume is) the desired result is
to use the date + integer operator:

select date_trunc('year', now())::date + (extract(doy from now()) - 1)::integer;
        regards, tom lane


Re: inverse of "day of year"

From
Martin Marques
Date:
El Vie 19 Mar 2004 12:10, Tom Lane escribió:
> Robert Creager <Robert_Creager@LogicalChaos.org> writes:
> > Martin Marques <martin@bugs.unl.edu.ar> confessed:
> >> Is there a function that would give me the date for a given day of year?
> >
> > Something like:
> >
> > select date_trunc( 'year', now() ) + (extract( doy from now() ) - 1) *
> > '1day'::interval;
>
> timestamp + interval arithmetic is likely to give you problems at
> daylight savings boundaries, since '1day' will be taken as '24hours'.

Is there information on how other intervals are taken? I mean, how is '1 year'
afected with the leap years?

-- 08:30:01 up 13 days, 13:01,  3 users,  load average: 2.04, 1.80, 1.04
-----------------------------------------------------------------
Martín Marqués        | select 'mmarques' || '@' || 'unl.edu.ar'
Centro de Telematica  |  DBA, Programador, Administrador            Universidad Nacional                 del Litoral
-----------------------------------------------------------------



Re: inverse of "day of year"

From
Bruno Wolff III
Date:
On Mon, Mar 22, 2004 at 08:32:32 -0300, Martin Marques <martin@bugs.unl.edu.ar> wrote:
> 
> Is there information on how other intervals are taken? I mean, how is '1 year' 
> afected with the leap years?

Intervals are stored as two components. One is absolute time difference,
and the other is in months. '1 year' is equivalent to '12 months'.
The documentation on how they work in corner cases (when added or subtracted
from timestamp(tz)) is sparse. It isn't documented whether the part in months
or the absolute time is added first or what timezone is used (for
timestamptz) when adding the months part.
The basic idea is that months are added by looking at the timestamp
as date and time and adding the appropiate number of months to the date
and then converting back to a timestamp. It isn't documented what happens
when the day of the month is past the end of the new month, but it looks
like the last day of new month is used.
If you convert an interval to an absolute time (such as by extracting the
epoch), then months are converted to 30 days. Again, I don't think this
is documented.


Re: inverse of "day of year"

From
Martin Marques
Date:
El Lun 22 Mar 2004 09:50, escribió:
>
> Intervals are stored as two components. One is absolute time difference,
> and the other is in months. '1 year' is equivalent to '12 months'.
> The documentation on how they work in corner cases (when added or
> subtracted from timestamp(tz)) is sparse. It isn't documented whether the
> part in months or the absolute time is added first or what timezone is used
> (for
> timestamptz) when adding the months part.
> The basic idea is that months are added by looking at the timestamp
> as date and time and adding the appropiate number of months to the date
> and then converting back to a timestamp. It isn't documented what happens
> when the day of the month is past the end of the new month, but it looks
> like the last day of new month is used.
> If you convert an interval to an absolute time (such as by extracting the
> epoch), then months are converted to 30 days. Again, I don't think this
> is documented.

Any thoughts on how this could affect date manipulation?

mydb=> select '29/2/2004'::date + ((2005 - date_part('year', now())::int) ||
'years')::interval;     ?column?
---------------------2005-02-28 00:00:00

AFAIKS with other dates this works OK. :-)

-- 10:11:02 up 13 days, 14:42,  4 users,  load average: 0.17, 0.12, 0.16
-----------------------------------------------------------------
Martín Marqués        | select 'mmarques' || '@' || 'unl.edu.ar'
Centro de Telematica  |  DBA, Programador, Administrador            Universidad Nacional                 del Litoral
-----------------------------------------------------------------



Re: inverse of "day of year"

From
Bruno Wolff III
Date:
On Mon, Mar 22, 2004 at 10:14:40 -0300, Martin Marques <martin@bugs.unl.edu.ar> wrote:
> 
> Any thoughts on how this could affect date manipulation?

This is consistant with what I explained about the behavior when adding
a month results in a day in a month past the end of the new month.
What do you expect to have happen here?

> mydb=> select '29/2/2004'::date + ((2005 - date_part('year', now())::int) || 
> 'years')::interval;
>       ?column?
> ---------------------
>  2005-02-28 00:00:00
> 
> AFAIKS with other dates this works OK. :-)

The real issue with intervals is that how they work in unusual cases is
not documented. The behavior could change in a future version without
much fanfare.


Re: inverse of "day of year"

From
Dana Hudes
Date:
If you have the option to handle the date manipulation in Perl
use the DateTime modules. Also see Date::Calc.
A considerable amount of effort has been expended dealing with all
the nitty-gritty of time manipulation.
Use those modules , get your new date or time interval and
feed that to the dbms with a straightforward inequality .
Don't try to do date arithmetic in sql if you can avoid it you'll
run afoul of something or other.

On Mon, 22 Mar 2004, Bruno Wolff III wrote:

> On Mon, Mar 22, 2004 at 10:14:40 -0300,
>   Martin Marques <martin@bugs.unl.edu.ar> wrote:
> > 
> > Any thoughts on how this could affect date manipulation?
> 
> This is consistant with what I explained about the behavior when adding
> a month results in a day in a month past the end of the new month.
> What do you expect to have happen here?
> 
> > mydb=> select '29/2/2004'::date + ((2005 - date_part('year', now())::int) || 
> > 'years')::interval;
> >       ?column?
> > ---------------------
> >  2005-02-28 00:00:00
> > 
> > AFAIKS with other dates this works OK. :-)
> 
> The real issue with intervals is that how they work in unusual cases is
> not documented. The behavior could change in a future version without
> much fanfare.
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
>     (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
> 


Re: inverse of "day of year"

From
Martin Marques
Date:
El Lun 22 Mar 2004 12:56, Dana Hudes escribió:
> If you have the option to handle the date manipulation in Perl
> use the DateTime modules. Also see Date::Calc.

NO!
Actualy what I'm doing is getting out of that (I'm using PHP's PEAR
Date::Calc) by creating some nice SQL and PL/PgSQL functions in the DB
server.

-- 11:01:02 up 14 days, 15:32,  4 users,  load average: 1.48, 1.11, 0.72
-----------------------------------------------------------------
Martín Marqués        | select 'mmarques' || '@' || 'unl.edu.ar'
Centro de Telematica  |  DBA, Programador, Administrador            Universidad Nacional                 del Litoral
-----------------------------------------------------------------