Отправка ежечасных уведомлений пользователям с учетом таймзоны
Всем привет! пишу небольшой проект, и хочу встроить туда ежечасную отправку уведомлений пользователям в заданных им границах и с учетом введенной временной зоны. В качестве базы используется Postgres, в качестве бэкенда golang. Пользователь вводит свою временную зону в формате числа, она сохраняется в базу(с умножением на -1, иначе работает некорректно) в текстовую ячейку(тут можно число преобразовывать в что-то вроде Europe/Berlin, но это не принципиально на мой взгляд). после этого пользователь вводит начало и конец временного промежутка в своем часовом поясе, в который он хочет получать уведомления(ввести необходимо только часы), все это сохраняется в базу. каждый час запускается ждоба, которая выбирает всех пользователей, которым нужно отправить уведомление. схема базы и запрос прилагаю:
users
+----+----+-------+-----+
| id | tz | start | end |
+----+----+-------+-----+
| 1 | -3 | 10 | 20 |
| 2 | 5 | 8 | 22 |
+----+----+-------+-----+
select * from users where start <= (select date_part('hour', (select (NOW() AT TIME zone "tz") from users))) and
end >= (select date_part('hour', (select (NOW() AT TIME zone "tz") from users)))
это работает, но выглядит довольно громоздко. может быть есть вариант сделать запрос аккуратнее или изначально иначе организовать хранение данных? буду рад любым идеям и предложениям!
Ответы (1 шт):
Если ты сделаешь хранение Europe/Berlin, то это автоматически решит проблему нецелых смещений и летнего времени.
create table tbl (
tz text,
start_h int,
end_h int
);
insert into tbl (tz, start_h, end_h)
values ('America/Los_Angeles', 8, 16);
insert into tbl (tz, start_h, end_h)
values ('Europe/Berlin', 8, 16);
with current_hour as (
SELECT
name tz,
date_part('hour', now() at time zone name) as h
FROM
pg_timezone_names
)
select
*
from
tbl
inner join current_hour using (tz)
where
current_hour.h between start_h and end_h
Причём список поддерживаемых таймзон прямо у Постгриса можно взять
select * FROM pg_timezone_names