Search Postgresql Archives

Re: Understanding years part of Interval

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> On 06/02/2023 18:33 CET Marcos Pegoraro <marcos@xxxxxxxxxx> wrote:
>
> Em seg., 6 de fev. de 2023 às 10:59, Erik Wienhold <ewie@xxxxxxxxx> escreveu:
> > > On 06/02/2023 12:20 CET Marcos Pegoraro <marcos@xxxxxxxxxx> wrote:
> >  >
> >  > I was just playing with some random timestamps for a week, for a month,
> >  > for a year ...
> >  >
> >  > select distinct current_date+((random()::numeric)||'month')::interval from generate_series(1,100) order by 1;
> >  > It´s with distinct clause because if you change that 'month' for a 'year'
> >  > it´ll return only 12 rows, instead of 100. So, why years part of interval
> >  > works differently than any other ?
> >  >
> >  > select '1.01 week'::interval; --> 0 years 0 mons 7 days 1 hours 40 mins 48.00 secs
> >  > select '1.01 month'::interval; --> 0 years 1 mons 0 days 7 hours 12 mins 0.00 secs
> >  > select '1.01 year'::interval; --> 1 years 0 mons 0 days 0 hours 0 mins 0.00 secs
> >
> >  Explained in https://www.postgresql.org/docs/15/datatype-datetime.html#DATATYPE-INTERVAL-INPUT:
> >
> >  Field values can have fractional parts: for example, '1.5 weeks' or
> >  '01:02:03.45'. However, because interval internally stores only
> >  three integer units (months, days, microseconds), fractional units
> >  must be spilled to smaller units. Fractional parts of units greater
> >  than months are rounded to be an integer number of months, e.g.
> >  '1.5 years' becomes '1 year 6 mons'. Fractional parts of weeks and
> >  days are computed to be an integer number of days and microseconds,
> >  assuming 30 days per month and 24 hours per day, e.g., '1.75 months'
> >  becomes 1 mon 22 days 12:00:00. Only seconds will ever be shown as
> >  fractional on output.
> >
> >  Internally interval values are stored as months, days, and
> >  microseconds. This is done because the number of days in a month
> >  varies, and a day can have 23 or 25 hours if a daylight savings time
> >  adjustment is involved.
> >
> I´ve sent this message initially to general and Erik told me it's documented,
> so it's better to hackers help me if this has an explaining why it's done that way.
>
> select '1 year'::interval = '1.05 year'::interval -->true ?
> I cannot agree that this select returns true.

The years are converted to months and the fractional month is rounded half up:

	1.05 year = 12.6 month
	=> 1 year 0.6 month
	=> 1 year 1 month        (after rounding)

Compare that to 12.5 months to see when the rounding occurs:

	12.5 month / 12 month
	=> 1.0416... years

Plug 1.0416 and 1.0417 into the interval to observe the rounding:

	=# select '1.0416 year'::interval, '1.0417 year'::interval;
	 interval |   interval
	----------+--------------
	 1 year   | 1 year 1 mon

--
Erik






[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]

  Powered by Linux