Дата и время.md 4.6 KB

~={yellow}Типы данных даты и времени=~

  • DATA - для хранения даты, то есть года, месяца и дня
  • TIME - для хранения времени, то есть часов, минут, секунд
  • TIME with time zone - для хранения времени с таймзоной
  • TIMESTAMP - для хранения даты и времени, то есть года, месяца, дня, часов, минут, секунд.
  • TIMESTAMPTZ - для хранения даты и времени с часовым поясом, что может быть удобно для приложений, которые работаю с разными часовыми поясами.
  • INTERVAL - для хранения промежутка времени, очень удобный тип данных.

~={yellow}Интервалы=~

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}Форматирование даты и времени=~

--- Создаем таблицу с полем 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 с явным указанием формата=~

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'), 'Ужас, всё работает!');

Выборка данных только за текущей месяц

-- Хорошо заходит функция trunc
select * from log
where date_trunc('month', created_at)=date_trunc('month', current_timestamp)
order by log_id;

Выборка данных за последнюю неделю

select * from log
where created_at >= current_date - interval '7 days'
order by created_at;

Удалить данные из таблицы, добавленные более чем 30 дней назад.

delete from log
where created_at < current_date - interval '30 days';

Работа с интервалами. Прибавить месяц.

select '2024-01-31'::date + '1 month'::interval;

Форматированный вывод timestamp

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() - вывод дельты

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;

Еще один пример выборки по дате

select email
from employees
where extract('month' from birthday)=4
order by email;

~={red}Важное=~

  • now() - это функция в postgres, в SQL - это CURRENT_TIMESTAMP