Jak uzyskać aktualną nazwę strefy czasowej w Postgres 9.3?

85

Chcę uzyskać aktualną nazwę strefy czasowej. To, co już osiągnąłem, to uzyskanie utc_offsetskrótu / strefy czasowej za pośrednictwem:

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

To daje mi wszystkie kombinacje Kontynent / Stolica dla tej strefy czasowej, ale nie dokładne timezone. Na przykład otrzymuję:

Europe/Amsterdam
Europe/Berlin

Serwer jest włączony Berlini chcę uzyskać nazwę strefy czasowej serwera.

Problem jaki mam z CETtym jest zawsze UTC+01:00i nie wyjaśnia DST iirc.

Deutro
źródło
Właściwa nazwa strefy czasowej dla Berlina i Amsterdamu to czas środkowoeuropejski (CET). Ogólnie nazwy i skróty stref czasowych nie są dobrze zdefiniowane; chociaż istnieje norma ISO, wiele krajów używa własnych definicji. Obsługa PostgreSQL również nie jest kompletna, zobacz postgresql.org/docs/9.4/static/datetime-config-files.html po więcej szczegółów.
Patrick,
1
W tabeli pg_timezone_names CET jest zdefiniowany jako skrót i np. „Europe / Berlin” jako nazwa. Potrzebuję nazwy, a nie skrótu.
Deutro,
Link, który podałem w poprzednim komentarzu, pokazuje, jak możesz edytować pliki, aby zapewnić to, czego potrzebujesz. To jest tak dobre, jak to tylko możliwe.
Patrick,
Więc nie ma sposobu, aby postgres powiedzieli mi, czy jestem w "Europie / Berlinie" czy "Europie / Amsterdamie", tylko że jestem w strefie czasowej CET?
Deutro,
Czy możesz edytować swoje pytanie i zdefiniować „Jestem w”? Serwer znajduje się (zwykle) w stałej lokalizacji, a strefa czasowa jest pobierana z systemu operacyjnego lub pliku konfiguracyjnego. Nazwa tz jest taka sama jak nazwa serwera. Czy naprawdę chcesz mieć nazwę strefy czasowej serwera lub danych w bazie danych?
Patrick,

Odpowiedzi:

121

Nie sądzę, aby było to możliwe przy użyciu samego PostgreSQL w najbardziej ogólnym przypadku. Instalując PostgreSQL, wybierasz strefę czasową. Jestem prawie pewien, że domyślnie jest używana strefa czasowa systemu operacyjnego. Zwykle będzie to odzwierciedlone w postgresql.conf jako wartość parametru „timezone”. Ale wartość kończy się jako „czas lokalny”. Możesz zobaczyć to ustawienie za pomocą instrukcji SQL.

show timezone;

Ale jeśli zmienisz strefę czasową w postgresql.conf na coś takiego jak „Europe / Berlin”, show timezone;zwróci wartość zamiast „localtime”.

Więc myślę, że twoje rozwiązanie będzie wymagało ustawienia "strefy czasowej" w postgresql.conf na jawną wartość zamiast domyślnego "czasu lokalnego".

Mike Sherrill `` Cat Recall ''
źródło
Dzięki za odpowiedź. Trochę dziwne, że nie można uzyskać strefy czasowej Systemu.
Deutro,
3
I ustawić strefę czasową, której możesz użyć set timezone to 'UTC'.
ivkremer
@ivkremer: set timezoneustawia strefę czasową dla jednej sesji klienta; nie ustawia strefy czasowej dla serwera PostgreSQL.
Mike Sherrill `` Cat Recall ''
@ MikeSherrill'CatRecall 'dziękuję, nie sprawdziłem tego.
ivkremer
25

To może, ale nie musi, pomóc w rozwiązaniu problemu, OP, ale aby uzyskać strefę czasową bieżącego serwera względem UTC ( UT1 , technicznie), wykonaj:

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

Powyższe działa poprzez wyodrębnienie względnego przesunięcia UT1 w minutach, a następnie przekształcenie go na godziny przy użyciu współczynnika 3600 sekund / godzinę.

Przykład:

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

( dokumenty ).

koyae
źródło
6
Inny użytkownik zasugerował użycie SELECT EXTRACT(TIMEZONE_HOUR FROM now()), ale jest to umiarkowanie niebezpieczne, ponieważ ignoruje fakt, że istnieją zarówno pół, jak i ćwierć strefy czasowej . @giladMayani
koyae
2
„Korea Północna, Nowa Fundlandia, Indie, Iran, Afganistan, Wenezuela, Birma, Sri Lanka, Markizy, a także niektóre części Australii stosują półgodzinne odchylenia od czasu standardowego. W niektórych krajach, takich jak Nepal, i w niektórych prowincjach, np. na wyspach Chatham użyj odchyleń co kwadrans. " ( link )
koyae
22

Wydaje się, że działa dobrze w Postgresql 9.5 :

SELECT current_setting('TIMEZONE');
KotGaf
źródło
Uruchomiłem twoje polecenie i zwróciło mi ono 15 200 wierszy, chociaż wszystkie mają tę samą strefę czasową.
Subhendu Mahanta
9

Zobacz odpowiedź: Źródło

Jeśli strefa czasowa nie jest określona w postgresql.conf lub jako opcja wiersza poleceń serwera, serwer próbuje użyć wartości zmiennej środowiskowej TZ jako domyślnej strefy czasowej. Jeśli TZ nie jest zdefiniowane lub nie jest żadną z nazw stref czasowych znanych PostgreSQL, serwer próbuje określić domyślną strefę czasową systemu operacyjnego, sprawdzając zachowanie funkcji biblioteki C localtime (). Domyślna strefa czasowa jest wybierana jako najbliższa pasująca spośród znanych stref czasowych PostgreSQL. (Reguły te są również używane do wybierania domyślnej wartości log_timezone, jeśli nie została określona). Source

Oznacza to, że jeśli nie zdefiniujesz strefy czasowej, serwer spróbuje określić domyślną strefę czasową systemu operacyjnego, sprawdzając zachowanie funkcji biblioteki C localtime ().

Jeśli strefa czasowa nie jest określona w postgresql.conf lub jako opcja wiersza poleceń serwera, serwer próbuje użyć wartości zmiennej środowiskowej TZ jako domyślnej strefy czasowej.

Wydaje się, że ustawienie strefy czasowej systemu jest rzeczywiście możliwe.

Pobierz lokalną strefę czasową systemu operacyjnego z powłoki. W psql:

=> \! date +%Z
Igoranze
źródło
2
date +%Zpolecenie zwróci strefę czasową klienta, a nie serwer, przez który się połączyłeśpsql
Eugen Konkov
9

Dostęp do strefy czasowej można uzyskać za pomocą następującego skryptu:

SELECT * FROM pg_timezone_names WHERE name = current_setting('TIMEZONE');
  • current_setting ('TIMEZONE') poda informacje o ustawieniach dotyczących kontynentu / stolicy
  • pg_timezone_names Widok pg_timezone_names zawiera listę nazw stref czasowych, które są rozpoznawane przez SET TIMEZONE, wraz ze skojarzonymi z nimi skrótami, przesunięciami czasu UTC i stanem czasu letniego.
  • nazwa Kolumna w widoku (pg_timezone_names) to nazwa strefy czasowej.

wynik będzie:

name- Europe/Berlin, 
abbrev - CET, 
utc_offset- 01:00:00, 
is_dst- false
Sachin R.
źródło