Oracle database and time zones - oracle

I'm working with an oracle database.
Every table got a creationdate and lastmodified field.
lastmodified is the actual time of the time zone ( UTC+1 + summer time if needed), while creationdate is the same time, but at UTC+0, leaving a difference of 2 hours in summer time and 1 hour otherwise.
Is there a way to change the creationdate so it's also using utc+1 + summer time when needed ? Thanks

You can use this one:
ALTER SESSION SET TIME_ZONE = 'Europe/Zurich';
SELECT
TO_TIMESTAMP_TZ(TO_CHAR(creationdate,'yyyymmddhh24miss"UTC"'), 'yyyymmddhh24missTZR') AT LOCAL AS creationdate_local_TIMESTAMP,
CAST(TO_TIMESTAMP_TZ(TO_CHAR(creationdate,'yyyymmddhh24miss"UTC"'), 'yyyymmddhh24missTZR') AT LOCAL AS DATE) AS creationdate_local_DATE
FROM your_table;
You must set you session time zone to region like above. If you use static value (e.g. ALTER SESSION SET TIME_ZONE = '+02:00';) it will not work properly.
Important note: if you update your table with converted time values, then you must ensure that you don't do it several times, because every update your time would be shifted by 1 or 2 hours again and again.

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

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

Daylight saving causing issue with scheduled job timing

I have a materialized view MVIEW_MY_AU which is getting refreshed from a stored procedure named REFRESH_MVIEWS_VIA_PRC. This SP contains following statement :
dbms_mview.refresh('MVIEW_MY_AU');
A job REFRESH_MVIEWS_VIA_SCH is created in all_scheduler_jobs table to execute this stored procedure.
Query :
select job_name, last_start_date,next_run_date,job_action from all_scheduler_jobs
where job_name = 'REFRESH_MVIEWS_VIA_SCH'
Output :
As per the scheduled job I am expecting this materialized view to get refresh at 3:30 AM Australia time. But when its getting refreshed at 4:30 AM Australia time as per the following query :
Query :
SELECT LAST_REFRESH
,TO_CHAR(last_refresh, 'MM/DD/YYYY HH24:MI:SS A.M.') as LAST_REFRESH_TIME
FROM user_mview_refresh_times
where name like 'MVIEW_MY_AU'
Output :
I started facing this issue after Daylight saving time for Australia started on 2nd Oct 2016. Is there any way to schedule the job which will take into consideration the day light saving time?
The are several ways that Oracle will consider daylight saving times.
Enter TIMESTAMP WITH TIME ZONE value for parameter start_time, e.g. SYSTIMESTAMP or CURRENT_TIMESTAMP
From DBMS_SCHEDULER Documentation:
When start_date is NULL, the Scheduler determines the time zone for
the repeat interval as follows:
It checks whether or not the session time zone is a region name. The session time zone can be set by either:
Issuing an ALTER SESSION statement, for example:
SQL> ALTER SESSION SET time_zone = 'Asia/Shanghai';
Setting the ORA_SDTZ environment variable.
If the session time zone is an absolute offset instead of a region name, the Scheduler uses the value of the DEFAULT_TIMEZONE Scheduler
attribute.
If the DEFAULT_TIMEZONE attribute is NULL, the Scheduler uses the time zone of systimestamp when the job or window is enabled.
Most important: Time zone must be provided as region, e.g. Australia/Sydney, not as UTC offset like +08:00
Regarding your query:
Column LAST_REFRESH of view user_mview_refresh_times is DATE data type, so by definition it does not contain any time zone information. Most likely column LAST_REFRESH is provided at your DB operating system server time zone (i.e. time zone value of SYSDATE). What is the time zone of your DB operating system server? You can determine this on OS directly or by
SELECT TO_CHAR(SYSTIMESTAMP, 'tzr') FROM dual;

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