Jetzt () ohne Zeitzone

72

Ich habe eine Spalte added_atdes Typs timestamp without time zone. Ich möchte, dass der Standardwert das aktuelle Datum und die aktuelle Uhrzeit ist, jedoch ohne Zeitzone. Die Funktionnow() gibt auch eine Zeitzone zurück.

Wie löse ich dieses Problem?

ア レ ッ ク ス
quelle
4
Aktuelles Datum-Uhrzeit wo? An deinem Schreibtisch? Am Server? Am Computer Ihres Benutzers? Datum und Uhrzeit ohne Zeitzone machen wenig Sinn.
2
@MikeW In der Umgebung, in der es ausgeführt wird.
レ ッ ク ス
Erwägen Sie die Verwendung with timestamp, insbesondere wenn Ihr Code überall dort ausgeführt wird, wo Sommerzeit verwendet wird. Oder sparen Sie die Zeit in UTC, nicht in einer lokalen Zeitzone. Sie können jederzeit wählen , welche Zeitzone Sie wollen in die Daten anzuzeigen.
einige
@some, ist das anders als with timezone?
レ ッ ク ス
8
Du missverstehst timestamp with time zone. Es hat überhaupt keine Zeitzone. Es ist nur in absoluter UTC-Zeit, mit Konvertierung in / von der Ortszeit in der TimeZoneSitzungsvariablen. Verwenden Sie einfach timestamp with time zone; Es ist fast immer die richtige Wahl.
Craig Ringer

Antworten:

85
SELECT now()::timestamp;

Die Besetzung konvertiert die timestamptzzurückgegebenen now()in die entsprechenden timestampin Ihrer Zeitzone - definiert durch die timezoneEinstellung der Sitzung. So wird auch die Standard-SQL-FunktionLOCALTIMESTAMP in Postgres implementiert.

Wenn Sie nicht in mehreren Zeitzonen arbeiten, funktioniert das einwandfrei. Andernfalls wechseln Sie zu timestamptzfür added_at. Der Unterschied?

Übrigens macht das genau das Gleiche, nur lauter und teurer:

SELECT now() AT TIME ZONE current_setting('timezone');
Erwin Brandstetter
quelle
select now()::timestamptz;ist ein besseres Spiel
Dmitriy Kosolobov
5
@DmitriKosolobov: now()kehrt bereits zurück timestamptz, now()::timestamptzmacht also nichts Nützliches.
Erwin Brandstetter
Ist das irgendwie besser als localtimestamp?
a_horse_with_no_name
now()::timestampMöglicherweise wird ein Casting durchgeführt, aber es wird für mich nicht von der lokalen Zeitzone in UTC konvertiert. Aber now() AT TIME ZONE 'UTC';macht das Richtige.
ThoPaz
1
@ThoPaz: Gibt now() AT TIME ZONE 'UTC'die Ortszeit für die Zeitzone UTC zurück. LOCALTIMESTAMPoder now()::timestampgeben Sie die Ortszeit für die aktuelle timezoneEinstellung der Sitzung zurück. Zwei verschiedene Dinge! Gibt nur dasselbe zurück, während Ihre aktuelle Sitzung mit ausgeführt wird timezone = 'UTC'.
Erwin Brandstetter
46

Nun, Sie können so etwas tun wie:

SELECT now() AT TIME ZONE current_setting('TimeZone');
SELECT now() AT TIME ZONE 'Europe/Paris';
SELECT now() AT TIME ZONE 'UTC';

Ich bin mir nicht sicher, wie das für eine Spalte "added_at" Sinn macht. Sie möchten fast immer einen absoluten Zeitstempel (Zeitstempel mit Zeitzone), keinen schwebenden.


Bearbeiten Sie die Antwort auf die folgenden Punkte:

  1. Ja, sollte einen Zeitstempel mit Zeitzone (absolute Zeit) verwenden, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.

  2. Die Client-Zeitzone wird von SHOW TimeZoneoder current_setting(...)wie oben gezeigt angegeben.

Nehmen Sie sich etwas Zeit, um die Handbücher zu überfliegen - sie decken das alles recht gut ab.

Richard Huxton
quelle
Wahrscheinlich ja. 1) Soll ich den Typ der Spalte ändern timestamp with time zone? 2) Woher weiß ich, wie aktuell die Zeitzone eines Computers ist, auf dem postgresql ausgeführt wird?
レ ッ ク ス
20

"Aktuelles Datum / Uhrzeit" :

CURRENT_TIME und CURRENT_TIMESTAMP liefern Werte mit Zeitzone. LOCALTIME und LOCALTIMESTAMP liefern Werte ohne Zeitzone.

Milen A. Radev
quelle
0

Neue und native Antwort im Jahr 2020

Wenn Sie in PostgreSQL nur die aktuelle Datums- und Uhrzeitangabe durch Aufrufen CURRENT_TIMESTAMP() ohne Zeitzone und gebrochene Ziffern im Sekundenfeld, die nach dem Dezimalpunkt des Sekundenfelds stehen , anzeigen möchten ?

(Getestet mit PostgreSQL v12.4)

Dann benutze dies:

SELECT CURRENT_TIMESTAMP(0)::TIMESTAMP WITHOUT TIME ZONE;

Wenn Sie den Datentyp Ihrer Spalte als timestamp(nicht als timestamptz) definieren, können Sie den Zeitstempel ohne Zeitzone speichern. In diesem Fall müssen Sie ihn nicht hinzufügenTIMESTAMP WITHOUT TIME ZONE

So was:

CREATE TABLE foo (created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP(0))

In der obigen Funktion wird 0 übergeben, um die gebrochenen Ziffern im Sekundenfeld zu entfernen.

Kaz
quelle