Timestamp in eine andere Zeitzone umwandeln

Hallo,

ich plage mich zur Zeit einwenig mit der Zeit rum. Das ist der Stand der Dinge:
Die Datenbank speichert die Zeit in der Zone UTC ab
Jetzt will ich eine Funktion schreiben, die der DB sagen, dass die folgende Zeit (v_dateinput) in einer anderen Zeitzone(v_timezone) liegt und diese in die Zeitzone UTC umrechnen soll.

declare
  tzrval        VARCHAR(20);
  v_dateinput   ALIAS FOR $1;
  v_timezone    ALIAS FOR $2;  
  time1         TIMESTAMP with time zone;   
  time2         TIMESTAMP with time zone;
  text1         text;
begin
  [..]
  -- ++ Zeit in Text umwandeln ++  
  Select to_char(v_dateinput, 'DD Mon YYYY HH12:MI:SS') INTO text1 ;
  -- ++ dem Text die Zeitzone '+01' hinzufügen. ++
    text1 := text1 || '+01';
  -- ++ Text in Zeit umwandeln ++ 
  Select to_TIMESTAMP( text1, 'DD Mon YYYY HH12:MI:SS') into time1;
  -- ++ Timestamp with time zone in die UTC Zeitzone umwandeln. ++
  Select timezone(v_timezone, time1) INTO time2 ;   
  -- ++ Zeitausgabe formatieren: HH12. ++    
  text1 := to_char(time2, 'DD Mon YYYY HH12:MI:SS');    
  -- ++ In Type Timestamp umwandeln. ++
  RETURN     to_TIMESTAMP( text1, 'DD Mon YYYY HH12:MI:SS') ;
end;

Diese Stelle funktioniert aber leider nicht:

  -- ++ dem Text die Zeitzone '+01' hinzufügen. ++
  text1 := text1 || '+01';
  -- ++ Text in Zeit umwandeln ++ 
  Select to_timestamp( text1, 'DD Mon YYYY HH12:MI:SS') into time1;

Obwohl ich im String die Zeitzone angebe, übernimmt er sie nicht bei der Funktion to_timestamp.

Könnt ihr mir helfen, wie ich das anderes machen kann?

liebe grüße
Lara

Mit

SET SESSION  TIME ZONE 1;

kann man die Zeitzone für eine Transaktion umstellen.

Wichtig ist nur, dass man die Zeit nicht vorher in ein Timestamp with time zone umwandelt. :stuck_out_tongue:

Ein Problem habe ich aber noch: Die Funktion soll auch die Zeitumstellung berücksichtigen. D. h. es soll in der Sommerzeit zwei Stunden zurück zählen und in der Winterzeit nur eine. Hat jemand eine Idee wie man das machen kann? Oder gibt es dafür schon eine Funktion? timezone( . , . ) macht das jedenfalls nicht. :frowning:

Also ich brauche immer noch eine Funktion oder ähnliches, die bei der Zeitzonen-Umwandlung auch die Zeitumstellung berücksichtigt. :frowning: Gibt es sowas bei PostgreSQL nicht?

select now() at time zone ‘GMT’

funktioniert irgendwie nicht bei Dir?

Andreas

Ich benutzte timezone( zone, time). Das müsste ja das gleiche sein.

Ich habe hier eine Funktion die ein “Timestamp with time zone” in die UTC Zeitzone umwandelt. Dabei wird mit dem Parameter “p_zone” mitgeteilt aus welcher Zone, die Zeit stammt.
Ich habe statt UTC auch schon GMT versucht, aber da hat es auch die Zeit (zB vom ‘2011-04-23 23:05:00’) nur um eine Stunde zurück gesetzt.

Die IF-ELSE-Abfrage von “v_zone” will ich eigentlich auch noch änderen. Aber
SET TIME ZONE v_zone;
funktioniert leider nicht. :frowning:

(Ich arbeite noch mit 8.4. Ich will meinen Betreuer noch fragen, ob wir diese updaten können …)

CREATE OR REPLACE FUNCTION  CONVERT_TO_UTC (TIMESTAMP with time zone, VARCHAR)
returns TIMESTAMP
as $$
declare
  v_zone        VARCHAR(20);
  p_time        ALIAS FOR $1;
  p_zone        ALIAS FOR $2;  
  v_time1       TIMESTAMP with time zone;  
  v_time2       TIMESTAMP with time zone;  
  v_text1       text;
begin                             
  IF LENGTH(p_zone) IS NULL THEN
    v_zone := 'GMT';
  else 
    v_zone := p_zone; 
  END IF;  
  -- ++ Timestamp with time zone in Text umwandeln
  select to_char(p_time, 'DD Mon YYYY HH24:MI:SS') into v_text1;
  if(v_zone in ('BST', 'CET', 'DNT', 'FST', 'MET', 'MEWT', 'MEZ', 'NOR', 'SET', 'SWT', 'WETDST')) then
    -- ++ Timestamp with time zone in die Zeitzone '+01' umwandeln. ++
    SET TIME ZONE 1;
    Select CONVERT_TO_UTC_EXEC(v_text1, 'UTC') into v_time1;
  elsif(v_zone in ('JST', 'KST', 'MHT', 'WDT', 'AWSST')) then
    SET TIME ZONE 9;
    -- ++ Timestamp with time zone in die Zeitzone '+09' umwandeln. ++
    Select CONVERT_TO_UTC_EXEC(v_text1, 'UTC') into v_time1;
  elsif(v_zone in ('GMT', 'UT', 'UTC', 'Z', 'ZULU', 'WET')) then
    -- ++ Zone wird nicht geändert ++
    v_time1 := p_time;
  else 
    raise exception 'unbekannte Zone - ist noch eine Baustelle';
  end if; 
  RETURN     v_time1 ;
end
$$
LANGUAGE 'plpgsql';



CREATE OR REPLACE FUNCTION  CONVERT_TO_UTC_EXEC (Text, Text)
returns TIMESTAMP
as $$
declare
  p_time        ALIAS FOR $1;
  p_zone        ALIAS FOR $2;  
  v_time1       TIMESTAMP with time zone;  
  v_time2       TIMESTAMP with time zone;  
  v_text1       text;
begin                                  
  select to_timestamp (p_time, 'DD Mon YYYY HH24:MI:SS') into v_time1 ; 
  -- ++ Timestamp with time zone in die UTC Zeitzone umwandeln. ++
  Select timezone( p_zone, v_time1) INTO v_time2 ;   
  -- ++ Zeitausgabe formatieren: HH12. ++    
  v_text1 := to_char(v_time2, 'DD Mon YYYY HH12:MI:SS AM');    
  -- ++ In Type Timestamp umwandeln. ++
  RETURN     to_timestamp( v_text1, 'DD Mon YYYY HH12:MI:SS AM') ;
end
$$
LANGUAGE 'plpgsql';