TIMESTAMP WITH LOCAL TIME ZONE
funciona así:cuando tiene que trabajar con zonas horarias en su aplicación, un enfoque común es
Así es exactamente como TIMESTAMP WITH LOCAL TIME ZONE
funciona - la única diferencia es
Por esa razón no puedes cambiar DBTIMEZONE
(con ALTER DATABASE SET TIME_ZONE='...';
) en su base de datos si la base de datos contiene una tabla con un TIMESTAMP WITH LOCAL TIME ZONE
columna y la columna contiene datos.
SYSTIMESTAMP
se devuelve en la zona horaria del sistema operativo del servidor de la base de datos. DBTIMEZONE
es no la zona horaria de SYSTIMESTAMP
o SYSDATE
.
DBTIMEZONE
define el formato de almacenamiento interno de TIMESTAMP WITH LOCAL TIME ZONE
columnas de tipo de datos. Olvida esto, no puedo imaginar ningún caso de uso en el que lo necesites.
En realidad, su tabla es equivalente a esta selección:
select
CAST(systimestamp AS timestamp(0) with local time zone) as SYSTIMESTAMP_COL,
CAST(sysdate AS timestamp(0) with local time zone) as SYSDATE_COL,
CAST(current_timestamp AS timestamp(0) with local time zone) as CURRENT_TIMESTAMP_COL,
CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone) as DATE_COL
from dual;
Cuando haces CAST({time without time zone} with local time zone)
luego intenta convertir un valor de fecha/hora sin ninguna información de zona horaria a un valor de fecha/hora con zona horaria. En principio, esto no es posible porque Oracle carece de la información de la zona horaria, por lo que Oracle asume una zona horaria. Si realiza dicha conversión, Oracle siempre considera {hora sin zona horaria} como se indica en SESSIONTIMEZONE
(en el momento de la conversión).
Así que CAST(sysdate AS timestamp(0) with local time zone)
es equivalente a
CAST(FROM_TZ(TO_TIMESTAMP(SYSDATE), SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)`
resp. CAST(timestamp '2017-03-15 19:02:00' AS timestamp(0) with local time zone)
significa
CAST(FROM_TZ(TIMESTAMP '2017-03-15 19:02:00', SESSIONTIMEZONE) AS TIMESTAMP(0) WITH LOCAL TIME ZONE)
Para SYSDATE
esto es realmente incorrecto, porque SYSDATE
se proporciona en la zona horaria del sistema operativo del servidor de la base de datos, no en SESSIONTIMEZONE. Para el segundo, depende de tu intención si el resultado es correcto o no.
SYSTIMESTAMP
devuelve el valor TIMESTAMP WITH TIME ZONE
, siempre es independiente de su SESSIONTIMEZONE
actual . Pero si convierte a TIMESTAMP WITH LOCAL TIME ZONE
se convierte a su zona horaria local actual, por supuesto. También puede usar CURRENT_TIMESTAMP
o SYSTIMESTAMP AT LOCAL
que hace más o menos lo mismo.
Este código
parece estar mal El resultado debe ser
-- SYSTIMESTAMP_COL 15/03/2017 16:01:14
-- SYSDATE_COL 15/03/2017 19:01:14
-- CURRENT_TIMESTAMP_COL 15/03/2017 16:01:14
-- DATE_COL 15/03/2017 19:02:00
Las diferencias se ven como deberían ser, pero los valores absolutos parecen ser "falsos" (o hay un problema real con su base de datos).