Konvertieren Sie einen Unix-Zeitstempel in eine DATETIME in einer Ansicht

7

Ich habe eine Tabelle, in der ein Unix-Zeitstempel gespeichert ist. Um dies als Datum abzufragen, versuche ich, diesen Zeitstempel in einer Ansicht in einen Datums- / Uhrzeittyp zu konvertieren. Leider kann ich nur scheinen, den DATE-Teil herauszubekommen.

Dieser Link beschreibt, wie die Konvertierung durchgeführt wird, erfordert jedoch eine Änderung des nls_date_formatZeitanteils. Die Standardeinstellung zeigt derzeit nur den Datumsanteil an. Ich brauche Datum und Uhrzeit.

Leider funktioniert diese Lösung nur auf Sitzungsebene. Als Entwickler möchte ich lieber nicht zu unserem Managed Service Provider gehen, um ihn zu bitten, den Wert auf Datenbankebene zu ändern - insbesondere, da dies Auswirkungen auf andere Anwendungen haben kann.

Gibt es eine Möglichkeit, den Zeitstempel in SQL in eine Datums- / Uhrzeitangabe zu konvertieren, ohne das System zu ändern?

Josh Smeaton
quelle

Antworten:

12

das Ergebnis des Ausdrucks

to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(1244108886,'SECOND')

ist ein Wert des Oracle-Datentyps DATE. Dieser Typ enthält Datum und Uhrzeit. Wenn Sie diesen Wert einem Benutzer anzeigen möchten, müssen Sie ihn in eine Zeichenfolge konvertieren. Diese Konvertierung kann von einer Anwendung durchgeführt werden, oder Sie können Oracle sie in einen Zeichenfolgentyp konvertieren lassen, wie in diesem Beispiel. Diese automatische Konvertierung in den Oracle-Stringtyp VARCHAR2 wird durch nls_date_format und einige Servereinstellungen gesteuert. Wenn Ihre Ansicht einen VARCHAR2-Wert mit dem berechneten Datum im Format 'JJJJ-MM-TT HH24: MI: SS' und nicht mit einem DATUM-Wert zurückgeben soll, können Sie dies mithilfe einer Konvertierungsfunktion: Ausdruck tun

to_char(to_date('1970-01-01','YYYY-MM-DD') + numtodsinterval(1244108886,'SECOND'),'YYYY-MM-DD HH24:MI:SS')

In diesem Fall ist der Rückgabewert der Ansicht jedoch ein VARCHAR2 und kein DATE-Wert.

Wunder173
quelle
5

Es wird empfohlen, Nicht-SQL-Funktionsaufrufe in SQL-Abfragen zu vermeiden, da die Funktion möglicherweise nicht universell verfügbar ist - in meinem System gibt es keine numtodsinterval-Funktion -, auch wegen des zusätzlichen Overheads beim Umschalten des Kontexts von SQL auf PL / SQL und dann Zurück zu SQL für jede zurückgegebene oder getestete Zeile, wenn die Funktion in der where-Klausel aufgerufen wird.

Hier ist eine reine SQL-Lösung.

TO_DATE('1970-01-01','YYYY-MM-DD') + unix_timestamp / 86400

Beachten Sie, dass das Ergebnis ein Oracle DATE-Wert ist, der auch die TIME enthält. Wenn beim Ausführen der Abfrage keine ZEIT angezeigt wird, liegt das Problem in Ihrem NLS_DATE_FORMAT oder in der Implementierung der Konvertierung von Datumsangaben in Zeichenfolgen durch Ihre Benutzeroberfläche. Stellen Sie sicher, dass Sie TO_CHAR selbst mit dem Zeitabschnitt in der Formatzeichenfolge ausführen, um den gesamten Wert anzuzeigen. zB TO_CHAR (a_date, 'jjjj-mm-tt hh24: mi: ss')

user21435
quelle
1

Ich habe eine andere Zahl verwendet, um diesen Wert zu berechnen.

select (TO_DATE('1970-01-01','YYYY-MM-DD') + unix_timestamp / 86400000) from dbname;

Dieses Skript funktioniert für mich in Ordnung.

bpedroso
quelle
Sieht für mich nicht gut aus.
Colin 't Hart
Es ist genau dann in Ordnung, wenn unix_timestamp in Millisekunden angegeben wird (was allerdings ziemlich ungewöhnlich wäre).
Frank Schmitt
Dies ist der Fall, wenn der Zeitstempel von Hibernate gespeichert wird.
Daniel Gray
Sehr häufig bei Java-Software im Allgemeinen, um einen Unix-Zeitstempel-ähnlichen Wert in Millisekunden zu speichern.
Dan Pritts
0

Wenn der unix_timestamp mit einem Datumsbereich in der WHERE-Klausel verglichen werden muss, ist es am besten, die Daten in unix_timestamps zu konvertieren, anstatt alle unix_timestamp-Werte in Datumsangaben zu konvertieren.

Im Folgenden finden Sie beispielsweise die Zeilen mit UNIX_TIMESTAMP zwischen dem angegebenen Start- und Enddatum.

WHERE unix_timestamp BETWEEN
       (:start_date - TO_DATE('1970-01-01','YYYY-MM-DD')) * 86400
       AND 
       (:end_date - TO_DATE('1970-01-01','YYYY-MM-DD')) * 86400

Dadurch kann auch ein Index für UNIX_TIMESTAMP verwendet werden, falls vorhanden.

user21435
quelle