During my prior post on the effect of daylight saving settings on the Oracle scheduler, I already pointed out that it is best to set your session timezone information to a named timezone and not to an absolute offset. In this post I would like to investigate how the session timezone settings affect the sysdate, current_date, systimestamp and current_timestamp variables during the switchover to or from daylight saving time. Current_date and current_timestamp, are using the date/time information of the server on which the database runs and modify that time using the timezone settings of the session.
As with the last post, the tests where done in response to the switching from wintertime to summertime, and I’m to lazy to redo them.
In the first test, I do not explicitly set timezone information in my session.
Both the server time and the client time has been set to a couple of minutes before the swithover from wintertime to summertime:
sys@GUNNAR> alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS'; Session altered. sys@GUNNAR> alter session set nls_timestamp_tz_format='DD/MM/YYYY HH24:MI:SS "TZ:" TZR "DS:" TZD '; Session altered. sys@GUNNAR> column systimestamp format a35 sys@GUNNAR> column current_timestamp format a35 sys@GUNNAR> select sysdate, current_date, systimestamp, current_timestamp from dual; SYSDATE CURRENT_DATE SYSTIMESTAMP CURRENT_TIMESTAMP ------------------- ------------------- ----------------------------------- ----------------------------------- 29/03/2009 01:58:32 29/03/2009 01:58:32 29/03/2009 01:58:32 TZ: +01:00 DS: 29/03/2009 01:58:32 TZ: +01:00 DS:
As you can see the timezone information uses the absolute offset notation and is set to GMT +1 (which corresponds with wintertime in Belgium).
After some minutes (when the summertime came in effect), I execute the same query again:
sys@GUNNAR> select sysdate, current_date, systimestamp, current_timestamp from dual; SYSDATE CURRENT_DATE SYSTIMESTAMP CURRENT_TIMESTAMP ------------------- ------------------- ----------------------------------- ----------------------------------- 29/03/2009 03:00:18 29/03/2009 02:00:18 29/03/2009 03:00:18 TZ: +02:00 DS: 29/03/2009 02:00:18 TZ: +01:00 DS:
Both sysdate and systimestamp has jumped 1 hour in the feature and systimestamp now shows the timezone as “GMT + 2” (summertime in Belgium).
Current_date and current_timestamp both show the time without summertime corrections, but with current_timestamp the timezone information places the time in the right context.
Next, I disconnect and reconnect the session:
sys@GUNNAR> select sysdate, current_date, systimestamp, current_timestamp from dual; SYSDATE CURRENT_DATE SYSTIMESTAMP CURRENT_TIMESTAMP ------------------- ------------------- ----------------------------------- ----------------------------------- 29/03/2009 03:01:15 29/03/2009 03:01:15 29/03/2009 03:01:15 TZ: +02:00 DS: 29/03/2009 03:01:15 TZ: +02:00 DS:
This time, all 4 show the same time and timezone information (all using summertime).
The explanation for this is that the timezone information for a session is determined when the session is created, and Oracle only applies daylight saving settings when using a named timezone. So as long as the session is connected, it uses the “old” timezone of GMT +1. With sysdate and systimestamp the timezone information comes from the server, not from the client.
In the second test, I have set the ORA_SDTZ variable in the client environment to “Europe/Brussels”
sys@GUNNAR> select sysdate, current_date, systimestamp, current_timestamp from dual; SYSDATE CURRENT_DATE SYSTIMESTAMP CURRENT_TIMESTAMP ------------------- ------------------- ----------------------------------- ----------------------------------------------- 29/03/2009 01:57:37 29/03/2009 01:57:38 29/03/2009 01:57:37 TZ: +01:00 DS: 29/03/2009 01:57:37 TZ: EUROPE/BRUSSELS DS: CET ### a couple of minutes later sys@GUNNAR> select sysdate, current_date, systimestamp, current_timestamp from dual; SYSDATE CURRENT_DATE SYSTIMESTAMP CURRENT_TIMESTAMP ------------------- ------------------- ----------------------------------- ------------------------------------------------ 29/03/2009 03:00:04 29/03/2009 03:00:04 29/03/2009 03:00:04 TZ: +02:00 DS: 29/03/2009 03:00:04 TZ: EUROPE/BRUSSELS DS: CEST
Both current_date and current_timestamp have now also jumped 1 hour in the “future” and the daylight saving settings in current_timestamp has changed from CET (Central European Time) to CEST (Central European Summer Time).
To me this shows that it is important to set the timezone of you clients correctly, even if the database is not used from different timezones.
A long running session is sufficient to pollute your data, certainly if you are using current_date as it has no timezone information.