функция age(timestamp, timestamp) считает не правильно

ZemA
Дата: 29.09.2004 11:31:42
Привет всем!
смотрите что творится
zstaff=# select age('01.03.04', '01.02.04');
   age
---------
 28 days
(1 row)
хотя
zstaff=# select age('01.02.04', '01.01.04');
  age
-------
 1 mon
(1 row)
wbear
Дата: 29.09.2004 15:17:49
а че в Тюмени разве 2001г был высокосным? :)

#select age('2004-03-01', '2004-02-01');
age
---------
29 days
(1 row)

#select age('2001-03-01', '2001-02-01');
age
---------
28 days
(1 row)

#select age('01.03.04', '01.02.04');
---------
1 days
(1 row)


дело в формате ,уменя (MM.DD.YY) ,а у тебя (YY.MM.DD)
гляди в сторону LC_TIME
ZemA
Дата: 29.09.2004 15:47:37
wbear
а че в Тюмени разве 2001г был высокосным? :)

нет с этим все нормально просто '01.03.04' это '01.03.2004'.

тем не менее
wbear

#select age('2004-03-01', '2004-02-01');
age
---------
29 days
(1 row)

почему 29 days должно быть 1 mons.

написал функцию на plpgsql, рабатает в 10 раз медленней чем age :(
CREATE OR REPLACE FUNCTION public.interval_between(date, date)
  RETURNS interval AS
'
declare
  from_date alias for $1;
  to_date   alias for $2;
  fday   integer := 0;
  fmonth integer := 0;
  fyear  integer := 0;
  tday   integer := 0;
  tmonth integer := 0;
  tyear  integer := 0;
  xyears integer := 0;
  xmons  integer := 0;
  xdays  integer := 0;
begin
  if from_date >= to_date then
    return 0;
  end if;

  fday   := date_part(\'day\', from_date);
  fmonth := date_part(\'month\', from_date);
  fyear  := date_part(\'year\', from_date);


  tday   := date_part(\'day\', to_date);
  tmonth := date_part(\'month\', to_date);
  tyear  := date_part(\'year\', to_date);

  if fday < tday then
    xdays := tday-fday;
  end if;

  if fday > tday then
    xmons := xmons-1;
    xdays := days_in_month(fyear, fmonth)-fday+tday;
  end if;

  if fmonth < tmonth then
    xmons := xmons + tmonth - fmonth;
  end if;

  if fmonth > tmonth then
    xmons := xmons + 12-fmonth+tmonth;
  end if;

  if fyear < tyear then
    xyears := tyear-fyear;
  end if;

  return ( (xyears || \' year\')::interval + (xmons || \' month\')::interval + (xdays || \' day\')::interval );
end;
'
  LANGUAGE 'plpgsql' VOLATILE;
попробуй запустить
Дата: 29.09.2004 18:32:18
select age('03.01.04'::date, '02.01.04'::date)::text AS "value", 'age' AS "name"
UNION ALL SELECT date_part('month','02.01.04'::date)::text, 'month'
UNION ALL SELECT date_part('day','02.01.04'::date)::text, 'day'
UNION ALL SELECT date_part('year','02.01.04'::date)::text, 'year';
ZemA
Дата: 29.09.2004 20:45:44
ну и что?
 value | name
-------+-------
 1 day | age
 1     | month
 2     | day
 2004  | year
(4 rows)
Shweik
Дата: 29.09.2004 20:56:13
По поводу первого поста.
tst=# select age('01.03.04', '01.02.04');
age
-------
1 mon
(1 row)
В чем проблема-то?
Может нужно посмотреть что напишет select version(); ???
У меня он пишет вот так:
tst=# select version();
version
-------------------------------------------------------------------
PostgreSQL 7.4 on i386-unknown-freebsd4.4, compiled by GCC 2.95.3
Видимо в твоем релизе действительно баг-с.
ZemA
Дата: 30.09.2004 09:49:14
Shweik
По поводу первого поста.
tst=# select age('01.03.04', '01.02.04');
age
-------
1 mon
(1 row)
В чем проблема-то?
Может нужно посмотреть что напишет select version(); ???
У меня он пишет вот так:
tst=# select version();
version
-------------------------------------------------------------------
PostgreSQL 7.4 on i386-unknown-freebsd4.4, compiled by GCC 2.95.3
Видимо в твоем релизе действительно баг-с.

вот
staff=# select version();
                              version
-------------------------------------------------------------------
 PostgreSQL 7.4 on i386-unknown-freebsd4.8, compiled by GCC 2.95.4
(1 row)

Проблемма в том что
staff=# select age('01.03.04', '01.02.04');
   age
---------
 28 days
(1 row)
staff=# select age('01.04.2004', '01.02.2004');
          age
------------------------
 1 mon 30 days 23:00:00
(1 row)
staff=# select age('01.05.2004', '01.02.2004');
           age
-------------------------
 2 mons 29 days 23:00:00
(1 row)
staff=# select age('01.06.2004', '01.02.2004');
           age
-------------------------
 3 mons 30 days 23:00:00
(1 row)
staff=# select age('01.06.2004', '01.03.2004');
          age
-----------------------
 3 mons 1 day 23:00:00
(1 row)
wbear
Дата: 30.09.2004 10:23:28
ну 23:00:00 это видимо из за перехода на летнее время.
а вот с днями хз. проще в исходники залезть и поглядеть при надобности поправить.
ZemA
Дата: 30.09.2004 11:36:54
В функции которую я написал есть ошибка.
вместо
  if fyear < tyear then
    xyears := tyear-fyear;
  end if;
нужно писать
  if fyear < tyear
  then
    xyears := tyear-fyear;
    if fmonth > tmonth then
      xyears := xyears-1;   
    end if;
  end if;
лениіец
Дата: 30.09.2004 11:58:51
А мож не стоит писать такое на plpgsql - сразу давай CPP functions!