Change timezone component of TIMESTAMP WITH TIMEZONE in Oracle - oracle

I have some data that is stored in a TIMESTAMP(6) WITH TIMEZONE column in Oracle, but it is stored in the wrong timezone. By convention, all timestamps in the DB must be stored in UTC, but this data was incorrectly persisted as EDT. The actual values are equivalent to the correct UTC value; the problem is simply that it is stored as 19-JUN-12 12.20.42.000000000 PM AMERICA/NEW_YORK when instead it should be 19-JUN-12 16.20.42.000000000 PM UTC. Is there any way in Oracle to change this?

Do you really need to change the data that is stored in the database? Normally, it's sufficient just to convert to a different time zone for display, i.e.
SELECT <<your_timestamp_column>> AT TIME ZONE 'UTC'
FROM <<your table>>
Of course, if you want to, you can also
UPDATE <<your table>>
SET <<your timestamp column>> = <<your timestamp column>> AT TIME ZONE 'UTC'
to change all the data.

Related

How does Oracle 12c handle Time Zone data in DATE datatype

I'm using Oracle Database 12c. I want to know how oracle manages timezone details for DATE datatype.
If i were to migrate data between time zones can i still get away with using DATE datatype? Or do i have to use TimeStamp or TimeStamp with TimeZone?
Does it keep the UTC time in DB and convert it when querying for results according to session time zone or some other NLS setting?
Thank you.
No, data type DATE does not handle any time zone information. Use data type TIMESTAMP WITH TIME ZONE or TIMESTAMP WITH LOCAL TIME ZONE
TIMESTAMP WITH TIME ZONE holds date + time + time zone
TIMESTAMP WITH LOCAL TIME ZONE holds date + time and these are stored internally in DBTIMEZONE (typically UTC). The value is always shown in the current user session time zone SESSIONTIMEZONE.
If you like to convert a DATE to TIMESTAMP WITH {LOCAL} TIME ZONE, then you must tell Oracle which time zone shall be used.
Typically you do it like this:
FROM_TZ(CAST({date_value} AS TIMESTAMP), 'desired time zone')
The cast is required because FROM_TZ requires a TIMESTAMP rather than a DATE
If you don't specify the time zone, e.g. like CAST({date_value} AS TIMESTAMP WITH TIME ZONE) then Oracle defaults the time zone to SESSIONTIMEZONE

Different timestamps for same sql query in Source Oracle Database and Target same Oracle Database while using Informatica

The source is having Createddate as 17-JAN-18 17.22.39.000000000 in my table.
When I execute the following query:
select CAST(Createddate AT TIME ZONE 'UTC' AS Timestamp) from Employee
on Oracle Database, It is giving below results.
17-JAN-18 15.22.39.000000000
But when I use the same SQL Query in Source Qualifier(Informatica) the target is getting below result which is in the same Oracle Database.
17-JAN-18 12.22.39.000000000
I am getting a 1 hour difference. Can someone help how can I get the same timestamp?
I assume your Createddate value is a TIMESTAMP value (without TIME ZONE).
When you run CAST(Createddate AT TIME ZONE 'UTC' AS Timestamp) then Oracle actually does
CAST(
FROM_TZ(Createddate, SESSIONTIMEZONE)
AT TIME ZONE 'UTC' AS Timestamp)
I.e. it appends the current session time zone to the timestamp value and then it is converted to new time zone.
So, the session time zones are different. The most reliable solution would be to set the time zone explicitly, e. g.
CAST(FROM_TZ(Createddate, 'Europe/Zurich') AT TIME ZONE 'UTC' AS Timestamp)
btw, for your function there is a shortcut, simply use like
SYS_EXTRACT_UTC(FROM_TZ(Createddate, 'Europe/Zurich'))

Trying to retrieve the UTC time-stamp in Oracle, does using "from_tz" cause an issue?

Will using the following query to retrieve the UTC timestamp from an oracle database cause an issue? I do not want to alter the database timezone parameter in order to retrieve the correct date. I do not want to do alter database set time_zone.
My query at the moment is:
select from_tz(CAST (sys_extract_utc(systimestamp) AS TIMESTAMP), '+00:00') from dual;
I would like to know if this query will result in the correct UTC date in all circumstances regardless of the EST/EDT status.
I don't see anything wrong with your query. Note that if you want to work in UTC for your session, you could simply:
ALTER SESSION SET TIME_ZONE = '0:00';
select CURRENT_TIMESTAMP from dual;
output
11/1/2016 5:48:55.115282 PM +00:00
That would change your current_timestamp (and localtimestamp) for your entire session.
Your query is just setting timezone but not converting time. If that's what you were looking for it is ok. Is local time is 3AM you will return 3AM UTC.
I think you're looking for that query:
select cast(sysdate as timestamp) at time zone 'UTC' from dual;
And the apply
select from_tz(cast(systimestamp at time zone 'UTC' as timestamp), '+0:00') from dual;
Some general notes:
SYSTIMESTAMP and SYSDATE are given in time zone of your database server's operating system. Thus changing database time zone (i.e. DBTIMEZONE) does not change anything.
CAST (sys_extract_utc(systimestamp) AS TIMESTAMP), resp. cast(systimestamp at time zone 'UTC' as timestamp) have a problem. You convert your timestamp to UTC but by CAST(... AS TIMESTAMP) you remove any time zone information from that value. If you like to do any further conversion (e.g. again to TIMESTAMP WITH TIME ZONE value) then your input UTC value is considered to be a SESSIONTIMEZONE value.
from_tz(CAST (sys_extract_utc(systimestamp) AS TIMESTAMP), '+00:00') does following:
Get current time in time zone of your database server's operating system, include time zone information.
Convert this time to UTC, cut time zone information
Append time zone information (+00:00) to this value
Correct output but redundant conversion
cast(sysdate as timestamp) at time zone 'UTC' does following:
Get current time in time zone of your database server's operating system, without any time zone information.
Cast to TIMESTAMP (basically no effect at all)
Consider this value as time in your local session time zone (SESSIONTIMEZONE) and convert to UTC.
Correct output only if time zone of your database server's operating system is the same as your local session time zone, otherwise you get wrong result.
from_tz(cast(systimestamp at time zone 'UTC' as timestamp), '+0:00') does following:
Get current time in time zone of your database server's operating system, include time zone information.
Convert this time to UTC
Cut time zone information
Append time zone information (+00:00) to this value
Correct output but redundant conversion
from_tz(cast(systimestamp as timestamp), '+0:00') does following:
Get current time in time zone of your database server's operating system, include time zone information.
Cut time zone information
Append time zone information (+00:00) to this value
Correct output only if time zone of your database server's operating system is UTC.

Convert Date Field to UTC in Oracle

I am trying to convert a date field 'createdate' to UTC time but the ask is to be -04:00. I have tried a bunch of things and have had no success. I am working on Oracle. Any ideas? Thank you.
This should do it:
cast(createdate as timestamp with time zone) at time zone 'UTC'
This converts the createdate to a timestamp with your current time zone (the one that is defined by your client through SESSIONTIMEZONE). It then converts that to UTC.
It is not possible if you have a DATE or TIMESTAMP value, because those data types do not have any time zone information and thus it is not possible to convert to any other time zone - unless you treat the value as "local time zone".
There are several solutions:
createdate at time zone 'UTC'
SYS_EXTRACT_UTC(createdate)
FROM_TZ(createdate, 'UTC')
The result types are different, e.g. FROM_TZ returns as TIMESTAMP WITH TIME ZONE values, whereas SYS_EXTRACT_UTC returns a TIMESTAMP value.

Oracle change dbtimezone

My database was configured with an dbtimezone=+2:00:
When my application sends a date which has a timezone, does Oracle automatically translate the date to its dbtimezone and store it in the column?
When my application asks for a field date, does Oracle automatically translate it to the application timezone?
In order to be consistency with business rules, I wanted to change this dbtimezone to UTC. So I made the alter database set time_zone='UTC' command, I restarted the oracle server and now the select dbtimezone from dual; command returns "UTC".
But, all fields date in DB haven't changed (no change -2 hours from GMT+2 to UTC). When I ask the sysdate, it returns the GMT+2 date ... I try to change my SQL Developer configuration timezone to UTC but it didn't change anything. Do I have an issue of Oracle session parameters that convert my DB data to GMT+2 before displaying it ?
Finally, does anyone have a good practice to make this change ? (change the database timezone and existing date to a new timezone).
If all you're doing is changing the database time zone setting, then you are only going to notice any change in output if your data is stored with the TIMESTAMP WITH LOCAL TIME ZONE type.
I don't recommend that though. It would be much better if your data was just stored in a regular TIMESTAMP field and was already set to UTC.
You should read the documentation about all of the different date and time datatypes, so you understand how each of these types works and differs from the other.

Resources