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

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.

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

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.

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

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.

How to handle Day Light Saving in Oracle database

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

Resources