Issue with timezone in oracle - 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.

Related

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

Oracle server timezone using SQL query

I ran
select SYSDATE from dual;
Output:
SYSDATE |
-------------------|
2019-10-09 08:55:29|
Then I ran,
SELECT DBTIMEZONE FROM DUAL;
Output:
DBTIMEZONE|
----------|
+00:00 |
In the first output, time is in EST and 2nd output suggests timezone is UTC.
How do I check oracle server timezone via SQL query?
From the docs:
The database time zone [DBTIMEZONE] is relevant only for TIMESTAMP WITH LOCAL TIME ZONE columns. Oracle recommends that you set the database time zone to UTC (0:00)...
SYSDATE/SYSTIMESTAMP will return the time in the database server's OS timezone. Selecting a TIMESTAMP WITH LOCAL TIME ZONE datatype will return the time in your session's timezone (ie, SESSIONTIMEZONE).
select
CAST(systimestamp AS timestamp(0) with local time zone) as local_time,
systimestamp as server_time
from dual;
DBTIMEZONE is only used as the base timezone stored in TIMESTAMP WITH LOCAL TIME ZONE columns - which you never see, because when you select from one of those columns it gets translated into your session timezone.
See this similar question for a very detailed answer.
It is a common misunderstanding that SYSDATE or SYSTIMESTAMP are returned at DBTIMEZONE
SYSDATE and SYSTIMESTAMP are given in the time zone of database server's operating system. If you like to interrogate the time zone of database server's operating system run
SELECT TO_CHAR(SYSTIMESTAMP, 'tzr') FROM dual;
see also How to handle Day Light Saving in Oracle database

Oracle DBTIMEZONE [duplicate]

In one of the Oracle database server it is showing "+01:00" when I fire the "Select dbtimezone from dual" does that mean in summer the clock will shift one hour ahead ?. In another server it is showing "+00:00" does that mean the database server setting is GMT ? but I am using the sysdate in oracle pl/sql. Client is saying the Aix server is on DST so would that mean the DB server will adopt the AIX server setting after clock change ?
How to fix this problem.
Answer is: It depends.
In total your database has three time zones
1. Your session time zone: SESSIONTIMEZONE
This you can change by ALTER SESSION SET TIME_ZONE=... at any time. It is relevant for result of
CURRENT_DATE
LOCALTIMESTAMP
CURRENT_TIMESTAMP
It is also the target time zone when you do CAST({TIMESTAMP/DATE without any timezone} AS TIMESTAMP WITH {LOCAL} TIME ZONE)
Default SESSIONTIMEZONE can be set by environment variable ORA_SDTZ or (on Windows) by registry entry HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_%ORACLE_HOME_NAME%\ORA_SDTZ (for 32 bit Client), resp. HKLM\SOFTWARE\ORACLE\KEY_%ORACLE_HOME_NAME%\ORA_SDTZ (for 64 bit Client).
2. The database time zone: DBTIMEZONE
Actually this is not so important in daily use, it is relevant only for TIMESTAMP WITH LOCAL TIME ZONE data type columns and defines the storage format.
This is NOT the timezone of SYSDATE or SYSTIMESTAMP!!!
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. Otherwise it can be changed with ALTER DATABASE SET TIME_ZONE='...';. The change does not take effect until the database has been shut down and restarted.
DBTIMEZONE is set when database is created. If no time zone is provided while database creation then Oracle defaults to the time zone of the server's operating system.
3. The time zone of database server's operating system:
This time zone is relevant for result of
SYSDATE
SYSTIMESTAMP
Naturally this time zone cannot be changed on database level. In case your home country uses Daylight Saving Times, this time zone may change twice a year. You can interrogate it with SELECT TO_CHAR(SYSTIMESTAMP, 'tzr') FROM dual;, for instance.
So, if your DB Server OS is setup properly, then you should get summer times from next week on (at least for Europe)
In one of the Oracle database server it is showing "+01:00" when I fire the "Select dbtimezone from dual" does that mean in summer the clock will shift one hour ahead ?
It means your database timezone is +01:00 compared to UTC time zone.
From docs,
DBTIMEZONE returns the value of the database time zone. The return
type is a time zone offset (a character type in the format
'[+|-]TZH:TZM') or a time zone region name, depending on how the user
specified the database time zone value in the most recent CREATE
DATABASE or ALTER DATABASE statement.
So, database's DBTIMEZONE inherits the timezone value from DB Server OS.
While SESSIONTIMEZONE could be overridden at session level by an alter session statement.
For example,
ALTER SESSION SET TIME_ZONE=<timezone>;
This modifies the time zone of the TIMESTAMP WITH LOCAL TIME ZONE.
In another server it is showing "+00:00" does that mean the database server setting is GMT ?
+00:00 can be assumed that the database time zone is set to UTC time zone.
For example,
SELECT DBTIMEZONE FROM DUAL;
DBTIME
------
+00:00
Read more from documentation.
I resolved this issue by using the below command
"Select Systimestamp at time zone 'GMT' from DUAL' This command wil always give the GMT date and time irrespective of OS time.
Oracle Database automatically determines whether Daylight Saving Time is in effect for a specified time zone and returns the corresponding local time. Normally, date/time values are sufficient to allow Oracle Database to determine whether Daylight Saving Time is in effect for a specified time zone. The periods when Daylight Saving Time begins or ends are boundary cases. For example, in the Eastern region of the United States, the time changes from 01:59:59 a.m. to 3:00:00 a.m. when Daylight Saving Time goes into effect. The interval between 02:00:00 and 02:59:59 a.m. does not exist. Values in that interval are invalid. When Daylight Saving Time ends, the time changes from 02:00:00 a.m. to 01:00:01 a.m.
Further explaination can be found here.
http://docs.oracle.com/cd/E18283_01/server.112/e10729/ch4datetime.htm#insertedID11

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.

Oracle 10g Time Zone Confusion

SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI')
,TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD HH24:MI')
,TO_CHAR(SYSTIMESTAMP, 'YYYY-MM-DD HH24:MI TZR')
,TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI TZR')
,TO_CHAR(LOCALTIMESTAMP, 'YYYY-MM-DD HH24:MI TZR')
,DBTIMEZONE
,SESSIONTIMEZONE
FROM DUAL;
Is returning:
2012-01-16 11:42
2012-01-16 11:42
2012-01-16 11:42 -06:00
2012-01-16 11:42 -06:00
2012-01-16 11:42 +00:00
+00:00
-06:00
It seems to think the database time zone is GMT, yet the SYSDATE is the same as the CURRENT_DATE.
When I remote into that server (Windows), the time zone is apparently CST (however, I am aware that this could be picking up my Terminal Services Client Time Zone Offset, but this machine doesn't have Terminal Services on it, just administrative)
Running the same thing against a server in Amsterdam (4 minutes later all from the same TOAD client), I'm getting:
2012-01-16 18:46
2012-01-16 11:46
2012-01-16 18:46 +01:00
2012-01-16 11:46 -06:00
2012-01-16 11:46 +00:00
+02:00
-06:00
Note the +2, but at least the SYSDATE and CURRENT_DATE are differing.
What is going on here? Where does SYSDATE come from and is there anything else which affects it?
It seems like DBTIMEZONE is not used for any of these things? So what is DBTIMEZONE used for?
There are actually 3 timezones here, not 2
the timezone of the session/client
Shown in SESSIONTIMEZONE
This is the timezone of CURRENT_DATE, LOCALTIMESTAMP and CURRENT_TIMESTAMP. The difference between those 3 is the return type, they return a DATE, TIMESTAMP, and TIMESTAMP WITH TIME ZONE respectively)
The database timezone
Shown in DBTIMEZONE
This is the the timezone used for the internal storage of TIMESTAMP WITH LOCAL TIME ZONE values. Note that values are converted to/from session timezone on insert/select so it actually isn't as important as it seems
This is NOT the timezone of SYSDATE/SYSTIMESTAMP
The database OS timezone
In unix, it is based on the TZ variable when Oracle is started
This is the timezone of SYSDATE and SYSTIMESTAMP
In your first example, I can see that the session TZ is UTC-6, the database TZ is UTC, and the database OS timezone is UTC-6.
In your second example, I can see that the session TZ is UTC-6, the database TZ is UTC+2, and the database OS timezone is UTC+1.
The details are in the fine print of the documentation. Take a look at the Return Type, and the actual Timezone the DATE or TIMESTAMP is calculated in.
SYSDATE
Return Type: DATE
Time Zone: Host OS of Database Server
CURRENT_DATE
Return Type: DATE
Time Zone: Session
SYSTIMESTAMP
Return Type: TIMESTAMP WITH TIME ZONE
Time Zone: Host OS of Database Server
CURRENT_SYSTIMESTAMP
Return Type: TIMESTAMP WITH TIME ZONE
Time Zone: Session
LOCALTIMESTAMP
Return Type: TIMESTAMP
Time Zone: Session
DBTIMEZONE
Time Zone: DB Time Zone. Inherits from DB Server OS, but can be overridden using set at DB Creation or Alter using TIME_ZONE DB Parameter (SET TIME_ZONE=...). This affects the time zone used for TIMESTAMP WITH LOCAL TIME ZONE datataypes.
SESSIONTIMEZONE
Time Zone: Session Timezone. Inherits from Session hosting OS, but can be overridden using ALTER SESSION (ALTER SESSION SET TIME_ZONE=...).
Return Type, indicates whether or not the Timezone is available within the Datatype. If you try to print TZR if datatype does not carry TimeZone, then it will just show up as +00:00 (doesn't mean it is GMT). Otherwise It will show the TimeZone matching either the Database or Session as indicated.
Time Zone, indicates in which Timezone the time is calculated. For matching TimeZone, the same Date/Time will be shown (HH24:MI).
Note that none of the FUNCTIONS return TIME in the Time Zone set with the DB TIME_ZONE (or as returned by the DBTIMEZONE function). That is, none of the functions also return a datatype of TIMESTAMP WITH LOCAL TIME ZONE. Howver you can convert the output of any of the functions that does return a timezone into a different timezone (including DBTIMEZONE) as follows:
SELECT SYSTIMESTAMP AT TIME ZONE DBTIMEZONE FROM DUAL;
More information on my blog.
Use UTC time and offset your timezone from UTC, To get UTC in Oracle use SYS_EXTRACT_UTC
Convert SYSTEMDATE to UTC
select sys_extract_utc(systimestamp) from dual;
As for the difference the definition from Oracle documentation might help to explain:
LOCALTIMESTAMP returns the current date and time in the session time zone in a value of datatype TIMESTAMP
CURRENT_TIMESTAMP returns the current date and time in the session time zone, in a value of datatype TIMESTAMP WITH TIME ZONE
SYSTIMESTAMP returns the system date, including fractional seconds and time zone, of the system on which the database resides
CURRENT_DATE returns the current date in the session time zone, in a value in the Gregorian calendar of datatype DATE.
SYSDATE returns the current date and time set for the operating system on which the database resides.
DBTIMEZONE returns the value of the database time zone.

Resources