Wie erhält man den numerischen Unterschied zwischen DBTIMEZONE und SESSIONTIMEZONE?

7

Gibt es in Oracle einen reibungslosen Weg, den numerischen Unterschied zwischen SESSIONTIMEZONE und DBTIMEZONE im aktuellen Moment (wenn ich den Anruf durchführe) zu erhalten?

Zum Beispiel:

%Vor%

Rückkehr:

%Vor%

Also, ich brauche eine Art von Funktion, indem ich mit gegebenen Parametern den Unterschied zwischen diesen beiden Werten erhalte.

Für die obige Instanz:

%Vor%

Würde -3 zurückgeben (das Zeichen ist entscheidend).

Natürlich ist es mir möglich, diese Funktion selbst zu schreiben, indem ich mit Strings arbeite und sie analysiere und dann arithmetische Operationen durchführe oder so etwas mache (was ich immer noch nicht für eine ziemlich glatte Lösung halte):

> %Vor%

Vielleicht habe ich etwas verpasst und Oracle bietet tatsächlich eine Möglichkeit, den Unterschied zwischen zwei gegebenen Zeitzonen zu berechnen?

    
ZZa 06.08.2013, 05:42
quelle

2 Antworten

14

Eine kleine Warnung zur Verwendung von SESSIONTIMEZONE

Ihr erstes Beispiel ist nicht kugelsicher, da für die Sitzungszeitzone einer der folgenden Werte festgelegt werden kann:

  • Zeitzone des Betriebssystems ( 'OS_TZ' )
  • Datenbankzeitzone ( 'DB_TZ' )
  • Absoluter Offset von UTC (z. B. '-05:00' )
  • Name der Zeitzonenregion (z. B. 'Europe/London' )

Schau dir einfach an, was hier passiert:

%Vor%

Das Parsen dieser 'Europa / Paris' Zeichenfolge in Ihrer Funktion wird sehr viel schwieriger ... Sie sollten die Funktion TZ_OFFSET verwenden, um sicherzustellen, dass Sie immer das gleiche ±HH:MM Format erhalten.

%Vor%

Über Ihre zweite Lösung

Ich denke, ich mag deine zweite Lösung besser. Sie können es verkürzen, indem Sie CURRENT_DATE anstelle von CAST(SYSTIMESTAMP AT TIME ZONE SESSIONTIMEZONE AS DATE) verwenden, sie sind äquivalent:

%Vor%

Sie könnten das technisch sogar tun!

%Vor%

ABER tatsächlich ist SYSDATE nicht garantiert in derselben Zeitzone wie DBTIMEZONE . SYSDATE ist immer an die Zeitzone des zugrunde liegenden Betriebssystems gebunden, während DBTIMEZONE nach dem Start des Servers geändert werden kann.

Und während ich Haare spalte, sollte ich euch auch daran erinnern, dass bestimmte Länder / Regionen Offsets verwenden, die keine ganzen Zahlen sind, zum Beispiel Iran Standardzeit ist UTC+03:30 , Myanmar Zeit ist UTC+06:30 ... ich don Ich weiß nicht, ob Sie jemals in Ihrer Produktionsumgebung darauf stoßen werden, aber ich hoffe, dass Sie mit der Möglichkeit einverstanden sind, dass Ihre Abfrage so etwas wie 1.5 ...

zurückgibt     
Miklos Aubert 12.08.2013, 08:32
quelle
5

Was Sie wollen, ist nicht möglich, da Zeitzonen nicht festgelegt sind, sondern sich im Laufe der Zeit ändern. Daher kann man NICHT den Unterschied zwischen zwei Zeitzonen berechnen, sondern nur die Differenz, die zu einem bestimmten Zeitpunkt gültig ist.

Es ist durchaus üblich, dass sich Zeitzonen im Laufe der Zeit ändern. In der TZ-Datenbank gibt es jedes Jahr viele Änderungen für die Zeitzonen, z. Orte, die ihre Zeitzone ändern, oder Änderungen am Anfang, am Ende oder an der Differenz der Zeit, an der die Zeit für das Licht gespeichert wird, oder Schaltsekunden, die zu "zufälligen" Zeiten eingefügt werden.

Um den Offset zu berechnen, müssen Sie also auch einen bestimmten Zeitpunkt angeben, für den der Offset berechnet werden soll (d. h. welche Version der Zeitzonendefinitionen angewendet werden soll).

Vor diesem Hintergrund wird deutlich, wie man den Unterschied zwischen zwei Zeitzonen zu einem bestimmten Zeitpunkt berechnen kann:

%Vor%

Wenn Sie diese Informationen haben, müssen Sie entscheiden, bis zu welcher Genauigkeit Sie den Unterschied wollen. Ich habe das obige Datum absichtlich gewählt, weil in dieser Nacht eine Schaltsekunde eingefügt wurde. Es könnte also einen Zeitpunkt geben, an dem Sie nicht genau neun Stunden, sondern neun Stunden und eine Sekunde unterscheiden (oder neun Stunden minus eine Sekunde).

Es ist auch wichtig, dass Sie die genauen Positionen und keine anderen Zeitstempelinformationen einfügen. Standorte können in verschiedene Zeitzonen wechseln. Daher müssen Sie die Schlepppositionen und einen Zeitpunkt angeben, um die richtige Zeitzonendifferenz zu erhalten.

Wenn Sie den Unterschied runden möchten, können Sie auf seine Komponenten mit EXTRACT(HOUR FROM ...) und EXTRACT(MINUTE FROM ...) zugreifen. Wenn Sie auf der zweiten Ebene runden möchten, können Sie den folgenden Trick verwenden:

%Vor%     
stefan.schwetschke 12.08.2013 13:12
quelle