Я храню в БД несколько параметров дата/время в виде TIMESTAMP WITH TIME ZONE. Как известно (документация), в постгресе всё это хранится в зоне UTC:
For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system’s TimeZone parameter, and is converted to UTC using the offset for the timezone zone.
Из-за этого преобразование распадается на два этапа:
1. привести к зоне сервера, на котором бегает постгрес;
2. привести к нужной зоне (к примеру, пользовательской).
Разберем итоговый запрос:
SELECT id, to_char(start_date :: TIMESTAMP AT TIME ZONE 'Europe/Moscow' at TIME Zone 'Europe/Samara','dd.mm.yyyy HH24:MI:SS'), to_char(end_date :: TIMESTAMP AT TIME ZONE 'Europe/Moscow' at TIME Zone (SELECT rr.zone FROM dk2k.russian_regions rr WHERE u.region_id = rr.id ), 'dd.mm.yyyy HH24:MI:SS') FROM dk2k.users u WHERE u.id=25; |
Форматирования дат происходит в двух строках. В обеих сначала дата приводится к зоне ‘Europe/Moscow’ — зоне моего сервера. В первой строке демонстрируется последующее приведение к фиксированной зоне ‘Europe/Samara’.
Во второй строке приведение уже к зоне пользователя, которая хранится в отдельной таблице (у каждого региона своя зона — проблемы будут с Якутией, у которой из-за огромного размера 3 часовых пояса).
Для наглядности в обоих случаях в формате участвуют часы, минуты и секунды — просто датой можно упустить какие-то частные случаи.