Як отримати поточну назву часового поясу в Postgres 9.3?


85

Я хочу отримати поточну назву часового поясу. Я вже домігся отримання utc_offsetабревіатури / часового поясу за допомогою:

SELECT * FROM pg_timezone_names WHERE abbrev = current_setting('TIMEZONE')

Це дає мені всі поєднання континент / столиця для цього часового поясу, але не точне timezone. Наприклад, я отримую:

Europe/Amsterdam
Europe/Berlin

Сервер знаходиться, Berlinі я хочу отримати ім’я часового поясу сервера.

У мене проблема з тим, CETщо вона завжди є UTC+01:00і не враховується DST iirc.


Правильна назва часового поясу для Берліна та Амстердама - центральноєвропейський час (CET). Загалом, назви часових поясів та скорочення недостатньо чітко визначені; хоча існує стандарт ISO, багато країн використовують власні визначення. Підтримка PostgreSQL також не завершена, см postgresql.org/docs/9.4/static/datetime-config-files.html для деяких деталей.
Патрік

1
У таблиці pg_timezone_names СЕВ визначається як абревіатура і, наприклад, "Європа / Берлін" як назва. Мені потрібно ім’я, а не абревіатура.
Deutro

Посилання, яке я дав у своєму попередньому коментарі, показує, як ви можете редагувати файли, щоб надати те, що вам потрібно. Це настільки добре, наскільки це вдається.
Патрік

Тож postgres не можуть сказати мені, чи перебуваю я в "Європі / Берліні" чи "Європі / Амстердамі", просто що я перебуваю в часовому поясі CET?
Deutro

Чи можете ви відредагувати своє запитання та визначити "Я перебуваю"? Сервер (зазвичай) знаходиться у фіксованому місці, а часовий пояс береться з операційної системи або файлу конфігурації. Ім'я tz фіксовано так само, як і сервер. То ви справді хочете ім’я часового поясу сервера чи даних у базі даних?
Патрік

Відповіді:


121

Я не думаю, що це можливо за допомогою лише PostgreSQL у найзагальнішому випадку. При встановленні PostgreSQL ви вибираєте часовий пояс. Я майже впевнений, що за замовчуванням використовується часовий пояс операційної системи. Це зазвичай відображається у postgresql.conf як значення параметра "часовий пояс". Але значення закінчується як "місцевий час". Ви можете побачити це налаштування за допомогою оператора SQL.

show timezone;

Але якщо ви зміните часовий пояс у postgresql.conf на щось на зразок "Європа / Берлін", тоді це значення show timezone;повернеться замість "localtime".

Тому я думаю, що ваше рішення передбачатиме встановлення "часового поясу" у postgresql.conf як явне значення, а не за замовчуванням "localtime".


Дякую за вашу відповідь. Дивно, що неможливо отримати часовий пояс систем.
Deutro

3
І для встановлення часового поясу ви можете використовувати set timezone to 'UTC'.
ivkremer

@ivkremer: set timezoneвстановлює часовий пояс для одного сеансу клієнта; він не встановлює часовий пояс для сервера PostgreSQL.
Mike Sherrill 'Cat Recall'

@ MikeSherrill'CatRecall 'дякую, я не перевіряв.
ivkremer

25

Це може допомогти вам вирішити вашу проблему, OP, але щоб отримати часовий пояс поточного сервера відносно UTC ( UT1 , технічно), виконайте:

SELECT EXTRACT(TIMEZONE FROM now())/3600.0;

Вищезазначене працює, витягуючи відносне зміщення UT1 за хвилини, а потім перетворюючи його на години, використовуючи коефіцієнт 3600 сек / год.

Приклад:

SET SESSION timezone TO 'Asia/Kabul';
SELECT EXTRACT(TIMEZONE FROM now())/3600.0;
-- output: 4.5 (as of the writing of this post)

( документи ).


6
Інший користувач запропонував використовувати SELECT EXTRACT(TIMEZONE_HOUR FROM now()), але це трохи небезпечно, оскільки він ігнорує той факт, що там є як половина, так і чверть часових поясів . @giladMayani
koyae

2
"Північна Корея, Ньюфаундленд, Індія, Іран, Афганістан, Венесуела, Бірма, Шрі-Ланка, Маркизькі острови, а також частини Австралії використовують півгодинні відхилення від стандартного часу. Деякі країни, такі як Непал, і деякі провінції, наприклад острови Чатем, використовуйте відхилення на чверть години ". ( посилання )
koyae

22

Здається, це прекрасно працює в Postgresql 9.5 :

SELECT current_setting('TIMEZONE');

Я виконав вашу команду, і вона повернула мені 15 200 рядків, хоча всі вони мають однаковий часовий пояс.
Subhendu Mahanta

9

Дивіться цю відповідь: Джерело

Якщо часовий пояс не вказаний у postgresql.conf або як параметр командного рядка сервера, сервер намагається використовувати значення змінної середовища TZ як часовий пояс за замовчуванням. Якщо TZ не визначено або не відоме PostgreSQL з назв часових поясів, сервер намагається визначити часовий пояс за замовчуванням операційної системи, перевіряючи поведінку функції бібліотеки C localtime (). Часовий пояс за замовчуванням обраний як найближчий збіг серед відомих часових поясів PostgreSQL. (Ці правила також використовуються для вибору значення за промовчанням log_timezone, якщо не вказано.) Джерело

Це означає, що якщо ви не визначите часовий пояс, сервер намагається визначити часовий пояс за промовчанням операційної системи, перевіряючи поведінку функції бібліотеки C localtime ().

Якщо часовий пояс не вказаний у postgresql.conf або як параметр командного рядка сервера, сервер намагається використовувати значення змінної середовища TZ як часовий пояс за замовчуванням.

Здається, встановити часовий пояс Системи можливо справді.

Отримайте з оболонки локальний часовий пояс ОС. У psql:

=> \! date +%Z

2
date +%Zкоманда поверне часовий пояс клієнта, а не той сервер, до якого ви підключилисьpsql
Євген Конков

9

Ви можете отримати доступ до часового поясу за таким сценарієм:

SELECT * FROM pg_timezone_names WHERE name = current_setting('TIMEZONE');
  • current_setting ('TIMEZONE') надасть вам інформацію про континент / столицю налаштувань
  • pg_timezone_names Представлення даних pg_timezone_names надає список назв часових поясів, які розпізнає SET TIMEZONE, а також пов'язані з ними абревіатури, зміщення UTC та стан переходу на літній час.
  • Ім'я стовпця у поданні (pg_timezone_names) - це назва часового поясу.

вихід буде:

name- Europe/Berlin, 
abbrev - CET, 
utc_offset- 01:00:00, 
is_dst- false
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.