mabn
mabn

Reputation: 2523

timezone-dependant systimestamp and timestamp comparison on Oracle

I've run into a weird situation. Could someone explain why comparison between timestamp and timestamp behaves as below (it depends on session timezone...). In addition outputed values are identical in all cases. It looks like timestamp inherits timezone from the session for comparison purposes, but for printing it does not?

Queries:

alter session set time_zone = '-6:0';
select cast(systimestamp as timestamp), systimestamp, case when cast(systimestamp as timestamp) < systimestamp then 'timestamp < systm' else 'timestamp >= systm' end as cmp from dual;
alter session set time_zone = '1:0';
select cast(systimestamp as timestamp), systimestamp, case when cast(systimestamp as timestamp) < systimestamp then 'timestamp < systm' else 'timestamp >= systm' end as cmp from dual;

output:

CAST(SYSTIMESTAMPASTIMESTAMP) SYSTIMESTAMP                        CMP              
----------------------------- ----------------------------------- ------------------
14/02/06 21:22:05,319973000   14/02/06 21:22:05,319973000 -06:00  timestamp >= systm 

session SET altered.
CAST(SYSTIMESTAMPASTIMESTAMP) SYSTIMESTAMP                        CMP              
----------------------------- ----------------------------------- ------------------
14/02/06 21:22:06,057183000   14/02/06 21:22:06,057183000 -06:00  timestamp < systm  

Database is in -6 timezone. Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production

Upvotes: 2

Views: 1923

Answers (2)

pavel_barbashov
pavel_barbashov

Reputation: 122

Look at this: https://docs.oracle.com/cd/B12037_01/server.101/b10749/ch4datet.htm#1006334

When you compare date and timestamp values, Oracle converts the data to the more precise datatype before doing the comparison. For example, if you compare data of TIMESTAMP WITH TIME ZONE datatype with data of TIMESTAMP datatype, Oracle converts the TIMESTAMP data to TIMESTAMP WITH TIME ZONE, using the session time zone. The order of precedence for converting date and timestamp data is as follows: 1. DATE 2. TIMESTAMP 3. TIMESTAMP WITH LOCAL TIME ZONE 4. TIMESTAMP WITH TIME ZONE For any pair of datatypes, Oracle converts the datatype that has a smaller number in the preceding list to the datatype with the larger number.

Upvotes: 1

Wernfried Domscheit
Wernfried Domscheit

Reputation: 59642

SYSTIMESTAMP returns a TIMESTAMP WITH TIME ZONE datatype. Looks like Oracle converts the TIMESTAMP to an TIMESTAMP WITH TIME ZONE datatype for comparison, actualy Oracle performs this:

SELECT
    CASE 
    WHEN CAST(CAST(SYSTIMESTAMP AS TIMESTAMP) AS TIMESTAMP WITH TIME ZONE) < SYSTIMESTAMP 
        THEN 'timestamp < systm' 
        ELSE 'timestamp >= systm' 
    END AS cmp 
FROM dual;

For conversion it takes the SESSION Timezone, you can check it with this query:

SELECT 
    EXTRACT(TIMEZONE_HOUR FROM CAST(CAST(SYSTIMESTAMP AS TIMESTAMP) AS TIMESTAMP WITH TIME ZONE)) AS TZ_HOUR
FROM dual;

You can discuss if this makes sense or not. For a correct conversion you better use FROM_TZ function, then it is under your control. SYSTIMESTAMP returns timestamp in DB timezone, so proper statement would be this one:

SELECT FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE), SYSTIMESTAMP, 
    CASE FROM_TZ(LOCALTIMESTAMP, DBTIMEZONE) < SYSTIMESTAMP THEN
    ...

Upvotes: 0

Related Questions