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

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'))

Related

Oracle timezone offset differs when run in sqlplus vs sql developer

Here's a puzzler. Take the following query and execute in oracle sqldeveloper:
select to_char(CAST (sysdate AS TIMESTAMP WITH TIME ZONE) ,'TZH:TZM') dst,
to_char(CAST (sysdate-160 AS TIMESTAMP WITH TIME ZONE) ,'TZH:TZM') nodst
from dual;
you will get the results of "-04:00", "-05:00". This gives the correct dst-adjusted timezone offset (eastern) with one date in dst, and the other not. Running the same query from sqlplus gives both values as "-4:00". This is causing a problem for a package that when called from sqlplus shows the incorrect value also.
When you cast to a timestamp with time zone, Oracle has to choose which time zone to use; and it uses the current session time zone. It's equivalent to doing:
select to_char(FROM_TZ(CAST (sysdate AS TIMESTAMP), SESSIONTIMEZONE) ,'TZH:TZM') dst,
to_char(FROM_TZ(CAST(sysdate-160 AS TIMESTAMP), SESSIONTIMEZONE) ,'TZH:TZM') nodst
from dual;
As you are getting different results in SQL Developer and SQL*Plus, you seem to have different session time zones in those two clients. You can check by querying sessiontimezone in each. SQL Developer sets the session time zone from the Java time zone (picked up from the operating system by default; you can override that by passing a user.timezone value at start-up). SQL*Plus uses the ORA_SDTZ environment variable, so you can set that to match your locale if you don't want to set it from within the database with alter session (manually or via login.sql); and if unset it defaults to 'OS_TZ':
The default value of the ORA_SDTZ variable, which is used when the variable is not set or it is set to an invalid value, is 'OS_TZ'.
... and it's picking that up as an offset (-04:00) rather than a region.
If you always want the result to be in a particular time zone regardless of any user's session settings, then you can state which one to use instead, e.g.:
select to_char(FROM_TZ(CAST (sysdate AS TIMESTAMP), 'America/New_York') ,'TZH:TZM') dst,
to_char(FROM_TZ(CAST(sysdate-160 AS TIMESTAMP), 'America/New_York') ,'TZH:TZM') nodst
from dual;
db<>fiddle with several session settings to demonstrate.
Presumably your real query is working from a variable date value, not sysdate; otherwise you could use systimestamp instead, with at time zone to adjust to a different zone if necessary.
This gives the correct dst-adjusted timezone offset (eastern) with one date in dst, and the other not.
No, it gives you a manually adjusted value that appears to be correct; however, when DST ends then your query will be incorrect and it will require adjusting ... then next spring it will require adjusting again ... and next autumn.
If you want the correct values then let Oracle adjust the time zones (and you don't need to cast SYSDATE to a TIMESTAMP WITH TIME ZONE, you can just use SYSTIMESTAMP or CURRENT_TIMESTAMP):
SELECT TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'US/Eastern', 'TZH:TZM')
AS timezone
FROM DUAL

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

Oracle PL/SQL How to get time in Paris?

What is the best way to always get the right time in Europe/Paris (including summer/winter times) ?
So far, I'm using the following query :
select FROM_TZ(CAST(Sysdate AS TIMESTAMP), 'Europe/Paris') from dual
It was working nicely in a previous server. However, we have changed our database server and now we are getting a difference of one hour.
Is there any way to get always the correct time in Paris ?
Thanks.
SYSDATE is returned in the time zone of database server's operating system. When you run FROM_TZ(CAST(Sysdate AS TIMESTAMP), 'Europe/Paris') then you "attach" time zone Europe/Paris to SYSDATE.
So, FROM_TZ(CAST(Sysdate AS TIMESTAMP), 'Europe/Paris') is only correct if the time zone of database server's operating system is Europe/Paris.
Try SYSTIMESTAMP AT TIME ZONE 'Europe/Paris' then result is always correct because SYSTIMESTAMP returns a TIMESTAMP WITH TIME ZONE value and time zones are properly converted.

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.

Issue with timezone in oracle

Below query is used in my code to get the timezone from database. (DB is in central time zone)
SELECT DBTIMEZONE FROM DUAL;
-05:00
When daylight saving is on (CDT), its expected result.
but when daylight saving ends (CST), my result should be GMT-06, but i am still getting GMT-05.
Googled and got below options :
SELECT TO_CHAR(SYSTIMESTAMP, 'TZR') FROM dual;
SELECT TZ_OFFSET('CST6CDT') FROM DUAL;
Will above queries run correctly accordingly to CST and CDT ??
DBTIMEZONE does not determine the time zone of SYSTIMESTAMP (or SYSDATE)
Time zone of SYSTIMESTAMP is the time zone of database server's operating system.
DBTIMEZONE is only relevant for data type TIMESTAMP WITH LOCAL TIME ZONE and defines the time zone in which those values are stored internaly. You cannot change DBTIMEZONE on your database if the database contains a table with a TIMESTAMP WITH LOCAL TIME ZONE column and the column contains data.

Resources