Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Работа с датами. / 25 сообщений из 27, страница 1 из 2
15.11.2005, 09:39
    #33378049
Michaelikus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Народ! ткните носом, плиз.
Есть ли в постгресе функции, позволяющие получать первый, последний дни месяца. Докуче привык ещё в оракле пользоваться конструкциями а-ля sysdate()+1 а вот в PgSQL now()+1 что-то не прокатывает.

В доках рылся, что-то пока ничего существенного не нашёл.
И пока пытаюсь выписать addmonth с помощью extract'a =)

Спасибо.
...
Рейтинг: 0 / 0
15.11.2005, 09:47
    #33378067
XM
XM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Michaelikus wrote:
> Народ! ткните носом, плиз.
> Есть ли в постгресе функции, позволяющие получать первый, последний дни
> месяца. Докуче привык ещё в оракле пользоваться конструкциями а-ля
> sysdate()+1 а вот в PgSQL now()+1 что-то не прокатывает.
>
> В доках рылся, что-то пока ничего существенного не нашёл.
> И пока пытаюсь выписать addmonth с помощью extract'a =)
>


Код: plaintext
1.
2.
3.
4.
5.
6.
-- Первый день тек. месяца
select date_trunc('month', now());
-- Последний день текущего месяца:
select date_trunc('month', now())+'1 month'::interval-'1 day'::interval;
-- Последний день пред. месяца:
select date_trunc('month', now())-'1 day'::interval;
:)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
15.11.2005, 10:21
    #33378182
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
XM
Код: plaintext
1.
2.
3.
4.
5.
6.
-- Первый день тек. месяца
select date_trunc('month', now());
-- Последний день текущего месяца:
select date_trunc('month', now())+'1 month'::interval-'1 day'::interval;
-- Последний день пред. месяца:
select date_trunc('month', now())-'1 day'::interval;
признайтесь таки, што фсе эти преобразования типа '1 day'::interval; или, шо хуже ("mytable"."days" ||' day')::interval - ретткий ийтиотизьм. Таки фнутре ш у её хте-то неонка (цифирь, т.е.)? т.ч. преобразование к техсту - турость.
...
Рейтинг: 0 / 0
15.11.2005, 11:28
    #33378452
XM
XM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
4321 wrote:
> признайтесь таки, што фсе эти преобразования типа '1 day'::interval;
> или, шо хуже ("mytable"."days" ||' day')::interval - ретткий ийтиотизьм.
> Таки фнутре ш у её хте-то неонка (цифирь, т.е.)? т.ч. преобразование к
> техсту - турость.

Если фнутренность этой цифири вывернуть, то имеем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
// src/include/utils/timestamp.h
typedef double Timestamp;

typedef struct
{
   double    time; /* all time units other than days, months and years */
   int32   day;    /* days, after time for alignment */
   int32   month;  /* months and years, after time for alignment */
} Interval;

// src/include/pgtime.h
struct pg_tm
{
   int     tm_sec;
   int     tm_min;
   int     tm_hour;
   int     tm_mday;
   int     tm_mon;     /* origin 0, not 1 */
   int     tm_year;    /* relative to 1900 */
   int     tm_wday;
   int     tm_yday;
   int     tm_isdst;
   long int  tm_gmtoff;
   const char *tm_zone;
};
и похоже, что SQL запросы (типа вышеприведенных) после разбора крутятся
внутри через pg_tm : timestamp2tm, interval2tm,... ну их к псям...

игого : если задавать interval цифирями, то имели бы синтаксис типа:
Код: plaintext
1.
interval( 10 , 2 , 3600 ) вместо '10 month 2 days 1 hour'::interval
???
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
15.11.2005, 14:30
    #33379226
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
XMну их к псям...солидарен

мдя-ссс. И хто бы разъяснил, откель такая напасть с датами в постгрессе? Мохабыть она, эта жуть в ришете, какие чудеса в поиске даётть-тьть? А то ш субейсы и M$ следом за ими обычным флоатом кажисть обошлись. Ачвидна -па нидамыслию, и отсутствию сурьезных академических наработок - некому было на путь истинный ванек наставить
...
Рейтинг: 0 / 0
15.11.2005, 15:27
    #33379426
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Может быть из-за переходов на змнее и летнее время и [возможных] других скачков времени.
...
Рейтинг: 0 / 0
15.11.2005, 15:32
    #33379442
Michaelikus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
уй ё!
Эка понаписали-та! =)))
А нет случайно перевода даты в юникстайм и назад. А то так может было бы и проще, чтоб велисипед не разрабатывать?
...
Рейтинг: 0 / 0
15.11.2005, 16:28
    #33379623
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Michaelikusуй ё!
Эка понаписали-та! =)))
А нет случайно перевода даты в юникстайм и назад. А то так может было бы и проще, чтоб велисипед не разрабатывать?EXTRACT(EPOCH FROM ...). См. доку 9.9. Date/Time Functions and Operators. А как из юникстайма получить первый и последний дни месяца?
...
Рейтинг: 0 / 0
15.11.2005, 16:36
    #33379653
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
доходит до маразма:
SELECT 982384720 * ('1 second'::INTERVAL);
11370 days 04:38:40"
т.е. - "туда дуй"
===
SELECT 982384720 * ('1 second'::INTERVAL)/('1 second'::INTERVAL);
ERROR: operator does not exist: interval / interval
HINT: No operator matches the given name and argument type(s). You may need to add explicit type casts.
т.е. "обратно - уйй"
т.е. прямая операция определена, обратная - нон фига.


приходицца:
SELECT EXTRACT(EPOCH FROM (982384720 * ('1 second'::INTERVAL)));
982384720

зато хоття бы сам дергает ее (EPOCH) из таймштампу
SELECT EXTRACT(EPOCH FROM ('epoch'::TIMESTAMP WITH TIME ZONE+(982384720 * ('1 second'::INTERVAL))));
982384720


___________________________
ЗЫ версия про скачки времен интересна. Вот только каким боком предложенная структура спасает (а обычные флоаты не пляшут)?
...
Рейтинг: 0 / 0
15.11.2005, 16:54
    #33379704
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
4321доходит до маразма:
SELECT 982384720 * ('1 second'::INTERVAL);
11370 days 04:38:40"
т.е. - "туда дуй"
===
SELECT 982384720 * ('1 second'::INTERVAL)/('1 second'::INTERVAL);
ERROR: operator does not exist: interval / interval
HINT: No operator matches the given name and argument type(s). You may need to add explicit type casts.
т.е. "обратно - уйй"
т.е. прямая операция определена, обратная - нон фига. В первом случае умножаете число на интервал, а во втором делите интервал на интервал. А разделить интервал на число можно.
...
Рейтинг: 0 / 0
15.11.2005, 17:23
    #33379774
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
LeXa NalBatВ первом случае умножаете число на интервал, а во втором делите интервал на интервал. А разделить интервал на число можно.дык если задана операция
TypA*TypB=TypC
то ничто не мешает задать 2 (две!) обратные операции
TypC/TypA = TypB
и
TypC/TypB =TypA

т.е. "ниппель" имеет место быть - одна из обратных операций не определена (што не имеет в данном случае нормальных оснований).

_______
т.ч. ваших соображений, почему интервал на интервал делить низзя - в упор не вижу. Размерность - одинакая (время), типы счислимые. Физиццки не запрещено часы делить на годы или века и получать числа. Правда могут быть возражения для лет - по длительности "физичесого" vs "календарного" года (високосность там и т.п.), опять таки скорость вращения (длительность дня/года) меняецца но тем не менее.
...
Рейтинг: 0 / 0
16.11.2005, 10:01
    #33380570
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
4321 LeXa NalBatВ первом случае умножаете число на интервал, а во втором делите интервал на интервал. А разделить интервал на число можно.дык если задана операция
TypA*TypB=TypC
то ничто не мешает задать 2 (две!) обратные операции
TypC/TypA = TypB
и
TypC/TypB =TypAВроде бы это не верно. К примеру, линейное пространство X. Определена операция y = a * x, где x, y C X, a C R. Легко определить оперцию y = x / a, через y = b * x, где b = 1/a C R. Но операции y / x, результатом которой было бы действительное число, нет. Еще пример, в постгресе определен оператор circle * point = circle, где circle - (x,y,z), point - (x,y). Но как можно определить обратную операцию circle / circle = point, операнды которой из трехмерного пространства, а результат из двухмерного?

4321т.ч. ваших соображений, почему интервал на интервал делить низзя - в упор не вижу. Размерность - одинакая (время), типы счислимые. Физиццки не запрещено часы делить на годы или века и получать числа.Соображений о невозможности деления интервала на интервал у меня нет. Есть только предположения, из-за чего это не реализовано - а) в силу (неизвестной мне:) некой непреодолимой логической трудности это невозможно, б) в силу технической трудности это относительно трудно реализуемо, поэтому пока не сделано (например, учитывать сдвиги времени (для каждой локали разные) проще (для программистов postgres) работая со структурой pg_tm, а не с числом, поэтому выбран этот тип, но реализовать деление таких структур труднее, чем чисел), в) это почти никому не нужно, поэтому не сделано. Если попытаться угадать, я бы предположил, что причина - случай б).
...
Рейтинг: 0 / 0
16.11.2005, 11:39
    #33380873
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
LeXa NalBat Вроде бы это не верно. К примеру, линейное пространство X. Определена операция y = a * x, где x, y C X, a C R. Легко определить оперцию y = x / a, через y = b * x, где b = 1/a C R. Но операции y / x, результатом которой было бы действительное число, нет.
[/quote]если деление на 0 неопределено, мы же не утверждаем что и деление на мн-ве целых (и т.п.) чисел не определено. Т.ч. если ветора некоего лин. пр-ва. коллинеарны, то и деление для них определено, а если нет - "переполнение" (Null или иное). (т.е. деление определено, пусть не "всюду", даже на таких "разнородных" объектах, как вектора.

"Вектора" же "интервалов" не являются независимыми. Вся проблема в смешивании в них релятивных (год, месяц) и абсолютных компонент (день, час, минута). Ктати, очень интересно посмотреть как сравниваются релятивные части (понятно, что год<>год (если сранивать "в абсолютных смыслах"), а вот в постгресе год=год. А далее со сравнениями ваапще бардак.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT INTERVAL '1 year'=INTERVAL '1 year' AS a,
INTERVAL '1 year'>=INTERVAL '365 days' AS b,
INTERVAL '1 year'<=INTERVAL '363 days' AS c,
INTERVAL '1 year'= INTERVAL '12 month' AS d,
 12  * INTERVAL '1 month'=INTERVAL '1 year' AS e,
INTERVAL '1 day' AS f,
INTERVAL '31 day'>=INTERVAL '1 month' AS g,
INTERVAL '31 day'<=INTERVAL '1 month' AS h,
INTERVAL '28 day'<=INTERVAL '1 month' AS h1,
INTERVAL '29 day'<=INTERVAL '1 month' AS h2,
INTERVAL '30 day'>=INTERVAL '1 month' AS h3,
 12 *INTERVAL '31 day'>= 12 *INTERVAL '1 month' AS i,
 12 *INTERVAL '31 day'>=INTERVAL '1 year' AS j,
INTERVAL '360 day'>=INTERVAL '1 year' AS k;
-----------
t;f;t;t;t;"1 day";t;f;t;t;t;t;t;t
если кто-то мне объяснит методы сравнения интервалов и рез-ты b,c,h3,j и k, то "велкам". Пока же я думаю, что надобно застрелить разработчиков временных типов в постгреса из духового ружжа. Шоб не мучились. Ибо нех.


кстати сказать без некоего розмысла неочевидно, будет ли результатом вычитания двух тайштампов интервал "в абсолютных" единицах, или "смешанного типа"?

[quot LeXa NalBat]Соображений о невозможности деления интервала на интервал у меня нет. Есть только предположения, из-за чего это не реализовано - а) в силу (неизвестной мне:) некой непреодолимой логической трудности это невозможно, б) в силу технической трудности это относительно трудно реализуемо, поэтому пока не сделано (например, учитывать сдвиги времени (для каждой локали разные) проще (для программистов postgres) работая со структурой pg_tm, а не с числом, поэтому выбран этот тип, но реализовать деление таких структур труднее, чем чисел), в) это почти никому не нужно, поэтому не сделано. Если попытаться угадать, я бы предположил, что причина - случай б).аппсплютно очивидно, шо релятивные части должны делицца на релятивные, аппсолютные -на аппсолютные, неколиннеарность "интервалов" возвращает неопределенность. Видимо нереализованно именно в силу смешанного релятивно/аппсолютного смысла интервала. (т.е. интервал это не время, а смесь относительных едениц и абсолютных, взятая в произвольном соотношении). Поэтому поддерживать на них большинство операций бессмысленно (возврат по большей части будет неопределен)

Странно, что для интервала определено сравнение. При наличии _ненулевых_ частей в относительной части сравнение должно производиться с некоторым лагом например:

год=год должно возвращать Null !!!
(или хотя бы (год= 365 дней)==Null)
как и
(месяц = месяц) == Null
но
(год+2 дня)>год =True
месяц >= месяц + 3дня

___
вот просветите меня, есь ли аппсолютные временные и интервальные типы в постгресе? (с определенными на них функциями, в том числе операциями с относительными временными понятиями).
...
Рейтинг: 0 / 0
16.11.2005, 11:41
    #33380875
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
LeXa NalBat Вроде бы это не верно. К примеру, линейное пространство X. Определена операция y = a * x, где x, y C X, a C R. Легко определить оперцию y = x / a, через y = b * x, где b = 1/a C R. Но операции y / x, результатом которой было бы действительное число, нет.
если деление на 0 неопределено, мы же не утверждаем что и деление на мн-ве целых (и т.п.) чисел не определено. Т.ч. если ветора некоего лин. пр-ва. коллинеарны, то и деление для них определено, а если нет - "переполнение" (Null или иное). (т.е. деление определено, пусть не "всюду", даже на таких "разнородных" объектах, как вектора.

"Вектора" же "интервалов" не являются независимыми. Вся проблема в смешивании в них релятивных (год, месяц) и абсолютных компонент (день, час, минута). Ктати, очень интересно посмотреть как сравниваются релятивные части (понятно, что год<>год (если сранивать "в абсолютных смыслах"), а вот в постгресе год=год. А далее со сравнениями ваапще бардак.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT INTERVAL '1 year'=INTERVAL '1 year' AS a,
INTERVAL '1 year'>=INTERVAL '365 days' AS b,
INTERVAL '1 year'<=INTERVAL '363 days' AS c,
INTERVAL '1 year'= INTERVAL '12 month' AS d,
 12  * INTERVAL '1 month'=INTERVAL '1 year' AS e,
INTERVAL '1 day' AS f,
INTERVAL '31 day'>=INTERVAL '1 month' AS g,
INTERVAL '31 day'<=INTERVAL '1 month' AS h,
INTERVAL '28 day'<=INTERVAL '1 month' AS h1,
INTERVAL '29 day'<=INTERVAL '1 month' AS h2,
INTERVAL '30 day'>=INTERVAL '1 month' AS h3,
 12 *INTERVAL '31 day'>= 12 *INTERVAL '1 month' AS i,
 12 *INTERVAL '31 day'>=INTERVAL '1 year' AS j,
INTERVAL '360 day'>=INTERVAL '1 year' AS k;
-----------
t;f;t;t;t;"1 day";t;f;t;t;t;t;t;t
если кто-то мне объяснит методы сравнения интервалов и рез-ты b,c,h3,j и k, то "велкам". Пока же я думаю, что надобно застрелить разработчиков временных типов в постгреса из духового ружжа. Шоб не мучились. Ибо нех.


кстати сказать без некоего розмысла неочевидно, будет ли результатом вычитания двух тайштампов интервал "в абсолютных" единицах, или "смешанного типа"?

LeXa NalBatСоображений о невозможности деления интервала на интервал у меня нет. Есть только предположения, из-за чего это не реализовано - а) в силу (неизвестной мне:) некой непреодолимой логической трудности это невозможно, б) в силу технической трудности это относительно трудно реализуемо, поэтому пока не сделано (например, учитывать сдвиги времени (для каждой локали разные) проще (для программистов postgres) работая со структурой pg_tm, а не с числом, поэтому выбран этот тип, но реализовать деление таких структур труднее, чем чисел), в) это почти никому не нужно, поэтому не сделано. Если попытаться угадать, я бы предположил, что причина - случай б).аппсплютно очивидно, шо релятивные части должны делицца на релятивные, аппсолютные -на аппсолютные, неколиннеарность "интервалов" возвращает неопределенность. Видимо нереализованно именно в силу смешанного релятивно/аппсолютного смысла интервала. (т.е. интервал это не время, а смесь относительных едениц и абсолютных, взятая в произвольном соотношении). Поэтому поддерживать на них большинство операций бессмысленно (возврат по большей части будет неопределен)

Странно, что для интервала определено сравнение. При наличии _ненулевых_ частей в относительной части сравнение должно производиться с некоторым лагом например:

год=год должно возвращать Null !!!
(или хотя бы (год= 365 дней)==Null)
как и
(месяц = месяц) == Null
но
(год+2 дня)>год =True
месяц >= месяц + 3дня

___
вот просветите меня, есь ли аппсолютные временные и интервальные типы в постгресе? (с определенными на них функциями, в том числе операциями с относительными временными понятиями).
...
Рейтинг: 0 / 0
16.11.2005, 11:57
    #33380942
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
кстати вот думаю, что и операции на них не подчиняюца перестановочным законам. Прибавить месяц,а потом 30 дней или прибавить 30 дней, а потом месяц - разные вестчи. Т.ч. сравнение для интервалов таки столь же неопределенная вещь, как и деление. (разве что "область определенности" поширше, а область неопределенности - поуже)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT INTERVAL '30 day' + INTERVAL '1 month' = INTERVAL '1 month' +  INTERVAL '30 day' AS a,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month' AS b,
'2000-01-01'::timestamp + INTERVAL '1 month'   + INTERVAL '30 day' AS b1,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month' = 
'2000-01-01'::timestamp + INTERVAL '1 month'   + INTERVAL '30 day' AS c,
'2000-01-01'::timestamp + (INTERVAL '30 day' + INTERVAL '1 month') =
 '2000-01-01'::timestamp + (INTERVAL '1 month'   + INTERVAL '30 day') AS c1,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month'
- INTERVAL '30 day' - INTERVAL '1 month' AS d
---------------
t;"2000-02-29 00:00:00";"2000-03-02 00:00:00";f;t;"1999-12-30 00:00:00"
...
Рейтинг: 0 / 0
16.11.2005, 12:05
    #33380974
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
т.е. пафос-то фсей бодяги ф томм, шо разница двух дат-времен есь величина аппсолютная, и должна выражацца в аппсолютных временных типах, а приводицца к смешанному типу токо по требованию. (ибо результат приведения зависит как от точки старта так и от пропорции разложения по аппсолютным и относительным составляющим). А вот для искомого аппсолютного временного типа сложение, умножения и деление _обязаны_ быть определены. А академические изыски - стронго фсад их аффтарам .
...
Рейтинг: 0 / 0
16.11.2005, 12:18
    #33381023
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
поправочка. Фместа Null для сравнения интервалов разработчикам предлагается ввести (куда-нть) несовсем определенный результат возврата ItDepends
...
Рейтинг: 0 / 0
16.11.2005, 12:44
    #33381136
XM
XM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
4321 wrote:
> вот просветите меня, есь ли аппсолютные временные и интервальные типы в
> постгресе? (с определенными на них функциями, в том числе операциями с
> относительными временными понятиями).

есть abstime, reltime - внутри цифирь int32 :)

Но проблема с интервалами следующая: должно быть два несовместимых типа
year-month, day-time.

SQL 1999 (не помню, откуда скачивал :)
....Year-month intervals are mutually comparable only with other
year-month intervals...

....Day-time intervals are mutually comparable only with other day-time
intervals...

Table 9 Valid operators involving datetimes and intervals
Operand 1 Operator Operand 2 Result TypeDatetime - Datetime IntervalDatetime + or - Interval DatetimeInterval + or - Datetime DatetimeInterval + or - Interval IntervalInterval * or / Numeric IntervalNumeric * Interval Interval


В PostgreSQL тип interval смешивает year-month, day-time, в результате
получается муйня.
Кроме того, имеем сомнительно корректные даты при
'2004-Feb-29'+'1 year' (т.е. примерно для 1% операций типа
дата+интервал(год-месяц) ) - даже по календарю корректно можем не попасть...
Еще фигня всякая когда год-месяц начинаем дробить...
( а-ля '2 mons -3 days -08:00:00' )

Прочие СУБД, похоже, забили на это в пользу тезисов:
"Дата - (дробное) кол-во секунд от (некоторой) точки отсчета.
Интервал - (дробное) кол-во секунд между двумя датами"
что, по-моему, в естественнонаучном плане - очень даже правильно :)

P.S. "Все врут календари" (c)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
16.11.2005, 14:08
    #33381515
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
XMполучается муйня.
...
P.S. "Все врут календари" (c)
аптом и ретчь.
Т.е. операции сравнения интервалов надо свершать оченно аккуратно, не забывая што это вестчи смешанные релятивно-аппсолютные. и сравнение для них в постгресе построенно в корне неверно. Радует только, что разница таймштампофф хотя и являецца интервалом, но таки, кажецца, интервалом исключительно в аппсолютных единицах:

SELECT '2013-01-01'::timestamp - '2000-01-01'::timestamp;
"4749 days"
(тип возврата interval)

vs
SELECT INTERVAL '12 year' + INTERVAL '365 day'
"12 years 365 days"
(тип возврата interval)

Т.е. для дельт таймштампов сравнение похоже должно быть пральным.
...
Рейтинг: 0 / 0
16.11.2005, 16:23
    #33382019
Michaelikus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Народ! огромное всем спасибо за принятое участие в дискуссии!!!
Как минимум я понял, на какое понятие опирается работа с датами в постгресе. Ну чтож, как говорится, у всех своя религия. Как у оракла все даты считаются относительно дня (тоесть 16.11.2005 + 1 = 17.11.2005) то в постгресе всё идёт в интервалах ;)

Хотя конечно не совсем приятно, когда нет чётких функций по определению временных параметров(первый день месяца, последний день..., дней в месяце).

Но в итоге конструкция now() + interval '1 day' меня порадовала. Хотя всё никак ещё не привыкну к явному приведению типов в интерпретаторе PGшки(сказывается оракловое "раздолбайство") ;).

В итоге накидал тут для себя несколько алгоритмов по определению интервалов дат:

-- Last day of month
select date_trunc('month', now()) + interval '1 month' - interval '1 day'

-- Days in month
select (date_trunc('month', now()) + interval '1 month') - date_trunc('month', now())

соответственно now() можно заменить на любой timestamp


ЗЫ. А жисть-то, налаживается!
...
Рейтинг: 0 / 0
16.11.2005, 16:36
    #33382078
XM
XM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
Michaelikus wrote:
> даты считаются относительно дня (тоесть 16.11.2005 + 1 = 17.11.2005)

Код: plaintext
select now()::date +  1 ;
:)
Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
17.11.2005, 10:29
    #33383326
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
XM SQL 1999 ....Year-month intervals...
немного думал. резюме такое:

интервальный тип должен обеспечивать сложение интервалов, но поскольку "месяц + 30 дней"<>"30 дней+месяц", то и интервалы эти разные. сталобыть интервал должен не только копить абсолютные и относительные "интервалы", но и порядок их следования. Свертка соседей (по порядку) допустима только для однотипных "элементалей" (Есть вырожденный случай, когда в неком участке массива набирается строго кратное 400 годам количество лет относительными интервальными типами "год" и "месяц" - тогда этот кусок массива можно свернуть до 2-х елементов в произвольном порядке). Т.е. интервал это "строка" или массив переменной длинны с элементами "чистых" типов. Суммирование и вычитание == дописывание вторго слагаемого (массива) в конец первого. Возможно со сверткой однотипных соседей. Предполагаемая структура элемента массива (value,typeOf) (можно вводить и месяца/годы других календарей). Как-то так. Интервальный тип же постгреса попросту вреден (см. сравнение, сложение и т.п.).
...
Рейтинг: 0 / 0
17.11.2005, 12:58
    #33383889
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
4321
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT INTERVAL '1 year'=INTERVAL '1 year' AS a,
INTERVAL '1 year'>=INTERVAL '365 days' AS b,
INTERVAL '1 year'<=INTERVAL '363 days' AS c,
INTERVAL '1 year'= INTERVAL '12 month' AS d,
 12  * INTERVAL '1 month'=INTERVAL '1 year' AS e,
INTERVAL '1 day' AS f,
INTERVAL '31 day'>=INTERVAL '1 month' AS g,
INTERVAL '31 day'<=INTERVAL '1 month' AS h,
INTERVAL '28 day'<=INTERVAL '1 month' AS h1,
INTERVAL '29 day'<=INTERVAL '1 month' AS h2,
INTERVAL '30 day'>=INTERVAL '1 month' AS h3,
 12 *INTERVAL '31 day'>= 12 *INTERVAL '1 month' AS i,
 12 *INTERVAL '31 day'>=INTERVAL '1 year' AS j,
INTERVAL '360 day'>=INTERVAL '1 year' AS k;
-----------
t;f;t;t;t;"1 day";t;f;t;t;t;t;t;t
если кто-то мне объяснит методы сравнения интервалов и рез-ты b,c,h3,j и k, то "велкам".Не знаю, правильно ли я разобрался. Обратите внимание на наличие функций justify_hours(interval) и justify_days(interval). Может быть они и используются при сравнении?

select interval '359 days' < interval '1 year', interval '360 days' = interval '1 year', interval '361 days' > interval '1 year';
?column? | ?column? | ?column?
----------+----------+----------
t | t | t

Но при этом date_part видимо эти функции не использует (и во втором случае наверное выдает unixtime от 1 января 1971 года):

select date_part( 'epoch', interval '360 days' ), date_part( 'epoch', interval '1 year' );
date_part | date_part
-----------+-----------
31104000 | 31557600

4321кстати вот думаю, что и операции на них не подчиняюца перестановочным законам. Прибавить месяц,а потом 30 дней или прибавить 30 дней, а потом месяц - разные вестчи. Т.ч. сравнение для интервалов таки столь же неопределенная вещь, как и деление. (разве что "область определенности" поширше, а область неопределенности - поуже)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT INTERVAL '30 day' + INTERVAL '1 month' = INTERVAL '1 month' +  INTERVAL '30 day' AS a,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month' AS b,
'2000-01-01'::timestamp + INTERVAL '1 month'   + INTERVAL '30 day' AS b1,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month' = 
'2000-01-01'::timestamp + INTERVAL '1 month'   + INTERVAL '30 day' AS c,
'2000-01-01'::timestamp + (INTERVAL '30 day' + INTERVAL '1 month') =
 '2000-01-01'::timestamp + (INTERVAL '1 month'   + INTERVAL '30 day') AS c1,
'2000-01-01'::timestamp + INTERVAL '30 day' + INTERVAL '1 month'
- INTERVAL '30 day' - INTERVAL '1 month' AS d
---------------
t;"2000-02-29 00:00:00";"2000-03-02 00:00:00";f;t;"1999-12-30 00:00:00"
Так это вы показали, что операция TIMESTAMP + INTERVAL = TIMESTAMP не перестановочна. И это вроде бы можно оправдать. А для операции INTERVAL + INTERVAL = INTERVAL я такого примера найти не смог.

4321интервальный тип должен обеспечивать сложение интервалов, но поскольку "месяц + 30 дней"<>"30 дней+месяц"Этого не наблюдается.

select interval '1 year' + interval '400 days', interval '400 days' + interval '1 year';
?column? | ?column?
-----------------+-----------------
1 year 400 days | 1 year 400 days
...
Рейтинг: 0 / 0
17.11.2005, 16:56
    #33384786
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
LeXa NalBat 4321интервальный тип должен обеспечивать сложение интервалов, но поскольку "месяц + 30 дней"<>"30 дней+месяц"Этого не наблюдается.

select interval '1 year' + interval '400 days', interval '400 days' + interval '1 year';
?column? | ?column?
-----------------+-----------------
1 year 400 days | 1 year 400 days неприятно удивлен.
читать надо таки то, что вам пишут, а не то, что вы хотите:
4321кстати вот думаю, что и операции на них не подчиняюца перестановочным законам. Прибавить месяц,а потом 30 дней или прибавить 30 дней, а потом месяц - разные вестчи. таким образом "это наблюдается" в "действительности" , но не наблюдаецца (как вы правильно заметили, а вам об этом и пытаются сообщить, чего вы не заметили) в постгрессовском способе работы с "интервалами" , который, таким образом, "фкорне" неверен. (не отражает положение дел с интервалами ф дефствителности)

а ваш результат на 1 месяце и 30 днях я вам уже получал и выше.
Или вы считаете, что
дата + 1 месяц + 30 дн = дата + 30 дн + 1 месяц
?
а дату такую не подскажете?

__________
и мне фсе равно, почему продухт неправильно работает, ежели я знаю, что идеология его к иному не приспособлена. (сравнение смешанных интервалов в постгре)
...
Рейтинг: 0 / 0
17.11.2005, 17:08
    #33384837
4321
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Работа с датами.
еще раз, "релятивные" интервалы - это функционалы, результат действия которых зависит от текущей даты к которой они плюсуюцца (т.е. от места в сногоместной сумме). Поэтому сравнить 2 "одинаковых" функционала нельзя. И перемещать функционалы в цепочке сложений тоже нельзя. Необходимо соблюдать заданный порядок. (Если на дату падает некий поток "воздействий" - добавляются и плюсуюца как абсолютные интервалы, так и месяцы, то результат зависит от порядка воздействий, таким образом просто накопить "в независимой", векторной структуре (как в посгре) оттдельно абсолютные, отдельно относительные воздействия и подействовать накопленными пачками на дату в том или ином порядке (сначала относительно, потом абсолютно или наоборот) просто нельзя. Так же нельзя сравнивать функционалы (месяцы и годы, лучше всего еврейского или иного подобного календаря, но сойдет и почти равномерный стандартный) в смысле сравнения "абсолютных" интервалов. А если сравнивать именно в таком, абсолютном смысле, придется вводить результат возврата ItDepends.
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Работа с датами. / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]