it-swarm.com.de

Konvertieren Sie den Zeitstempeldatentyp in den Unix-Zeitstempel Oracle

Ich habe einen Zeitstempeldatentyp in einer Datenbank mit dem Format 24-JuL-11 10.45.00.000000000 AM und möchte, dass er in einen Unix-Zeitstempel konvertiert wird. Wie kann ich ihn erhalten?

7
deepti

Diese Frage ist so ziemlich das Gegenteil von Unixtime nach Datetime SQL (Oracle) konvertieren

Wie Justin Cave sagt:

Es gibt keine eingebauten Funktionen. Aber es ist relativ einfach, einen zu schreiben. Da ein Unix-Zeitstempel die Anzahl der Sekunden seit dem 1. Januar 1970 ist

Da das Entfernen zweier Daten voneinander die Anzahl der Tage zwischen ihnen ergibt, können Sie Folgendes tun:

create or replace function date_to_unix_ts( PDate in date ) return number is

   l_unix_ts number;

begin

   l_unix_ts := ( PDate - date '1970-01-01' ) * 60 * 60 * 24;
   return l_unix_ts;

end;

Da es in Sekunden seit 1970 ist, ist die Anzahl der Sekundenbruchteile unerheblich. Sie können es trotzdem mit einem Zeitstempeldatentyp aufrufen ...

SQL> select date_to_unix_ts(systimestamp) from dual;

DATE_TO_UNIX_TS(SYSTIMESTAMP)
-----------------------------
                   1345801660

Als Antwort auf Ihren Kommentar tut es mir leid, aber ich sehe dieses Verhalten nicht:

SQL> with the_dates as (
  2    select to_date('08-mar-12 01:00:00 am', 'dd-mon-yy hh:mi:ss am') as dt
  3      from dual
  4     union all
  5    select to_date('08-mar-12', 'dd-mon-yy')
  6      from dual )
  7  select date_to_unix_ts(dt)
  8    from the_dates
  9         ;

DATE_TO_UNIX_TS(DT)
-------------------
         1331168400
         1331164800

SQL>

Es gibt 3.600 Sekunden Unterschied, d. H. 1 Stunde.

17
Ben

Mir ist klar, dass eine Antwort bereits akzeptiert wurde, aber ich denke, es sollte klargestellt werden, dass die Funktion in dieser Antwort den Zeitzonenversatz des übergebenen Datums nicht berücksichtigt. Ein richtiger Unix-Zeitstempel sollte bei GMT (+0) berechnet werden. Die to_date -Funktion von Oracle geht davon aus, dass das übergebene Datum in der lokalen Zeitzone liegt, sofern nicht anders angegeben. Dieses Problem wird durch die Tatsache verschärft, dass die Sommerzeit eine echte Sache ist. Ich habe dieses Problem mit der folgenden Funktion gelöst:

create or replace
  function unix_time_from_date
      (
        in_date   in date,
        in_src_tz in varchar2 default 'America/New_York'
      )
    return integer
  as
    ut      integer       := 0;
    tz      varchar2(8)   := '';
    tz_date timestamp with time zone;
    tz_stmt varchar2(255);
  begin
    /**
     * This function is used to convert an Oracle DATE (local timezone) to a Unix timestamp (UTC).
     *
     * @author James Sumners
     * @date 01 February 2012
     *
     * @param in_date An Oracle DATE to convert. It is assumed that this date will be in the local timezone.
     * @param in_src_tz Indicates the time zone of the in_date parameter.
     *
     * @return integer
     */

    -- Get the current timezone abbreviation (stupid DST)
    tz_stmt := 'select systimestamp at time zone ''' || in_src_tz || ''' from dual';
    execute immediate tz_stmt into tz_date;
    select
      extract(timezone_abbr from tz_date)
    into tz
    from dual;

    -- Get the Unix timestamp
    select
      (new_time(in_date, tz, 'GMT') - to_date('01-JAN-1970', 'DD-MM-YYYY')) * (86400)
    into ut
    from dual;

    return ut;
end unix_time_from_date;

Ich habe einige Begleitfunktionen, unix_time und unix_time_to_date, verfügbar unter http://jrfom.com/2012/02/10/Oracle-and-unix-timestamps-revisited/ . Ich kann nicht glauben, dass Oracle es bis zu 11g geschafft hat, ohne diese zu implementieren.

11
James Sumners

Ich verwende die folgende Methode, die sich ein wenig von anderen Antworten darin unterscheidet, dass sie die Funktion sessiontimezone() verwendet, um das Datum richtig abzurufen

    select
    ( 
      cast((FROM_TZ(CAST(in_date as timestamp), sessiontimezone) at time zone 'GMT') as date) -- in_date cast do GMT
      - 
      TO_DATE('01.01.1970','dd.mm.yyyy') -- minus unix start date
    )
    * 86400000 -- times miliseconds in day
    from dual;
1
dpedro

für Datum:

   FUNCTION date_to_unix (p_date  date,in_src_tz in varchar2 default 'Europe/Kiev') return number is
begin
    return  round((cast((FROM_TZ(CAST(p_date as timestamp), in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60));
end;

für Zeitstempel:

FUNCTION timestamp_to_unix (p_time  timestamp,in_src_tz in varchar2 default 'Europe/Kiev') return number is
    begin
        return  round((cast((FROM_TZ(p_time, in_src_tz) at time zone 'GMT') as date)-TO_DATE('01.01.1970','dd.mm.yyyy'))*(24*60*60));
    end;
1
Andre Kirpitch

Für die Umrechnung zwischen Oracle-Zeit und Unix-Zeiten benutze ich diese Funktionen. Sie berücksichtigen Ihre aktuelle Zeitzone. Sie sollten auch das Schlüsselwort DETERMINISTIC hinzufügen, wenn Sie beispielsweise eine solche Funktion in einem funktionsbasierten Index verwenden möchten. Die Konvertierung zwischen DATE und TIMESTAMP sollte implizit von Oracle durchgeführt werden.

FUNCTION Timestamp2UnixTime(theTimestamp IN TIMESTAMP, timezone IN VARCHAR2 DEFAULT SESSIONTIMEZONE) RETURN NUMBER DETERMINISTIC IS
    timestampUTC TIMESTAMP;
    theInterval INTERVAL DAY(9) TO SECOND;
    epoche NUMBER;
BEGIN
    timestampUTC := FROM_TZ(theTimestamp, timezone) AT TIME ZONE 'UTC';
    theInterval := TO_DSINTERVAL(timestampUTC - TIMESTAMP '1970-01-01 00:00:00');
    epoche := EXTRACT(DAY FROM theInterval)*24*60*60 
        + EXTRACT(HOUR FROM theInterval)*60*60 
        + EXTRACT(MINUTE FROM theInterval)*60 
        + EXTRACT(SECOND FROM theInterval);
    RETURN ROUND(1000*epoche);
END Timestamp2UnixTime;



FUNCTION UnixTime2Timestamp(UnixTime IN NUMBER) RETURN TIMESTAMP DETERMINISTIC IS
BEGIN
    RETURN (TIMESTAMP '1970-01-01 00:00:00 UTC' + UnixTime/1000 * INTERVAL '1' SECOND) AT LOCAL;
END UnixTime2Timestamp;
0
SELECT (SYSDATE - TO_DATE('01-01-1970 00:00:00', 'DD-MM-YYYY HH24:MI:SS')) * 24 * 60 * 60 * 1000 FROM DUAL
0
Piotr R

Das habe ich mir ausgedacht:

select    substr(extract(day from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 24 * 60 * 60 + 
          extract(hour from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 * 60 + 
          extract(minute from (n.origstamp - timestamp '1970-01-01 00:00:00')) * 60 + 
          trunc(extract(second from (n.origstamp - timestamp '1970-01-01 00:00:00')),0),0,15) TimeStamp 
          from tablename;

FWIW

0
rogerdpack