~={yellow}Типы данных даты и времени=~ - DATA - для хранения даты, то есть года, месяца и дня - TIME - для хранения времени, то есть часов, минут, секунд - TIME with time zone - для хранения времени с таймзоной - TIMESTAMP - для хранения даты и времени, то есть года, месяца, дня, часов, минут, секунд. - TIMESTAMPTZ - для хранения даты и времени с часовым поясом, что может быть удобно для приложений, которые работаю с разными часовыми поясами. - INTERVAL - для хранения промежутка времени, очень удобный тип данных. ~={yellow}Интервалы=~ ```sql select now(), now() + '1 hour'; select now(), now() + '1 day'; select now(), now() + '1 month'; select now(), now() - '1 month'::interval; select now(), now() - '1 hour'::interval; select now(), now() - '1 year'::interval; select now(), now() - '1 year 1 month'::interval; select now(), now() - '1 year 1 month 1 hour'::interval; select now(), now() - '1 year 1 month 1 hour 1 minute'::interval; select now(), now() - '1 year 1 month 1 hour 1 minute 1 second'::interval; ``` ~={yellow}Форматирование даты и времени=~ ```sql --- Создаем таблицу с полем timestamp create table log( log_id bigint generated always as identity, created_at timestamp not null default current_timestamp, message text not null ); -- Добавляем данные insert into log (message) values ('Произошло страшное: сломался прием платежа'), ('Трындец с отправкой почты, похоже, почтовый сервер недоступен!'), ('Ужас, все работает!'); -- Забиарем данные в нужном формате timestamp select to_char(created_at, 'DD.MM.YYYY HH24:MI:SS') as "дата инцидента", message as "сообщение" from log; ``` ~={yellow}Правильная вставка timestamp с явным указанием формата=~ ```sql insert into log (created_at, message) values (to_timestamp('31.07.2024 20:19:51', 'DD.MM.YYYY HH24:MI:SS'), 'Произошло страшное: сломался приём платежа #1128'), (to_timestamp('31.07.2024 17:19:52', 'DD.MM.YYYY HH24:MI:SS'), 'Трындец с отправкой почты, похоже, почтовый сервер недоступен!'), (to_timestamp('31.07.2024 17:20:53', 'DD.MM.YYYY HH24:MI:SS'), 'Ужас, всё работает!'); ``` Выборка данных только за текущей месяц ```sql -- Хорошо заходит функция trunc select * from log where date_trunc('month', created_at)=date_trunc('month', current_timestamp) order by log_id; ``` Выборка данных за последнюю неделю ```sql select * from log where created_at >= current_date - interval '7 days' order by created_at; ``` Удалить данные из таблицы, добавленные более чем 30 дней назад. ```sql delete from log where created_at < current_date - interval '30 days'; ``` Работа с интервалами. Прибавить месяц. ```sql select '2024-01-31'::date + '1 month'::interval; ``` Форматированный вывод timestamp ```sql select to_char(start, 'DD.MM.YYYY') start, to_char(finish, 'DD.MM.YYYY') finish, extract(days from finish - start) delta_in_days from records order by start, finish; ``` Примем использования age() - вывод дельты ```sql select age('2024-06-21 01:38:11'::timestamp, '2021-01-24 01:12:48'::timestamp); -- 3 years 4 mons 28 days 00:25:23 select extract(day from age('2024-06-21 01:38:11'::timestamp, '2021-01-24 01:12:48'::timestamp)); -- 28 select extract(days from age('2024-06-21 01:38:11'::timestamp, '2021-01-24 01:12:48'::timestamp)); -- 28 select extract(years from age('2024-06-21 01:38:11'::timestamp, '2021-01-24 01:12:48'::timestamp)); -- 3 select to_char(start, 'DD.MM.YYYY') start, to_char(finish, 'DD.MM.YYYY') finish, age(finish, start) delta from records order by start, finish; ``` Еще один пример выборки по дате ```sql select email from employees where extract('month' from birthday)=4 order by email; ``` ~={red}Важное=~ - now() - это функция в postgres, в SQL - это CURRENT_TIMESTAMP -