Convert epoch time to timestamp in oracle database with system timezone - sql

Can someone please suggest me how to convert epoch time to timestamp in oracle including the database timezone. I am currently using below code:
cast ( TO_TIMESTAMP_TZ('1970-01-01 00:00:00.0 UTC', 'YYYY-MM-DD HH24:MI:SS.FF TZR') + NUMTODSINTERVAL(value/1000, 'SECOND') as timestamp with local time zone)
But it appears this is converting to the sessiontimezone. I need it to be converted to dbtimezone
(In my case select dbtimezone gives PST time and select sessiontimezone gives Asia/Calcutta time.)

Data type timestamp with local time zone always shows date/time at SESSIONTIMEZONE
Try
(TO_TIMESTAMP_TZ('1970-01-01 00:00:00.0 UTC', 'YYYY-MM-DD HH24:MI:SS.FF TZR') + NUMTODSINTERVAL(value/1000, 'SECOND')) AT TIME ZONE DBTIMEZONE
Or with literals:
(Timestamp '1970-01-01 00:00:00 UTC' + value/1000 * INTERVAL '1' SECOND) AT TIME ZONE DBTIMEZONE

Related

Subtracting hours from Unix Timestamp

The following query selects a unix timestamp. It should be 1pm but says 5pm because of UTC. It needs to be Eastern time 1pm, so I need to subtract 4 hours from it. What's the best way to go about this?
SELECT CAST(to_date('1970-01-01', 'YYYY-MM-DD') + substr(STARTTIME,0,10)/60/60/24 as timestamp)
You shouldn't caluclate manually. You should add or substract the timezone.
Oracle how to convert time in UTC to the local time (offset information is missing)
Here an example-query:
SELECT TO_CHAR (
FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'UTC')
AT TIME ZONE 'EUROPE/BERLIN',
'YYYY-MM-DD HH24:MI:SS TZH:TZM TZR')
AS BERLIN_Time_complete,
TO_CHAR (
FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'UTC')
AT TIME ZONE 'UTC',
'YYYY-MM-DD HH24:MI:SS TZH:TZM TZR')
AS UTC_Complete,
TO_CHAR (
FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'UTC')
AT TIME ZONE 'EUROPE/BERLIN',
'YYYY-MM-DD HH24:MI:SS TZH:TZM')
AS BERLIN_Time_complete,
TO_CHAR (
FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'UTC')
AT TIME ZONE 'EUROPE/BERLIN',
'TZH:TZM')
AS BERLIN_Timezone,
TO_CHAR (
FROM_TZ (CAST (SYSDATE AS TIMESTAMP), 'UTC')
AT TIME ZONE 'EUROPE/BERLIN',
'TZR')
AS Timezone_Name
FROM DUAL;
The key is for Format:
YYYY: Year with four digits (0000-9999 ex: 2018)
MM: Month with two digits (01-12)
DD: Day with two digits (01-31)
HH24: Hour 00-23
MI: Minutes 00-59
SS: Seconds 00-59
TZH: Timezone-Hours
TZM: Timezone-Minutes (There are timezones with 30mins offset)
TZR: Name of the timezone
You should play around with those, to understand the to_date()/to_char(). You'll need it.
If you realy want to add hours. Here an example:
select sysdate + INTERVAL '2' HOUR from dual;
You can try this :
SELECT TO_CHAR(sysdate, 'DD-MON-YYYY HH24:MI:SS') AS myDate
FROM dual;
For more information read this document.

Inserting timestamp with timezone in text in SQL

I created an insert statement that inserts the current time into a field with datatype:
TIMESTAMP(6) WITH TIME ZONE
insert into(
...
)
values(
9645
,0
,CAST(CURRENT_TIMESTAMP AS TIMESTAMP WITH TIME ZONE)
,user
,CAST(CURRENT_TIMESTAMP AS TIMESTAMP WITH TIME ZONE)
,0
,'APPROVED_P'
,1
,1
)
This works fine, but for one problem
I would like to have the timezone in text as well, but I'm unable to find a solution. Hope someone can help me out.
Time zone +01:00 is not the same as CET. Mayor difference is CET considers daylight saving times whereas +01:00 does not.
If you want time zone CET then you must set your session time zone accordingly with ALTER SESSION SET TIME_ZONE = 'CET'; or you set CURRENT_TIMESTAMP AT TIME ZONE 'CET' instead of CURRENT_TIMESTAMP
You should see the difference when you run this:
SELECT SESSIONTIMEZONE,
TO_CHAR(CURRENT_TIMESTAMP, 'yyyy-mm-dd hh24:mi:ss tzh:tzm tzr tzd'),
TO_CHAR((current_TIMESTAMP - INTERVAL '6' MONTH), 'yyyy-mm-dd hh24:mi:ss tzh:tzm tzr tzd')
FROM DUAL;

Different results for TO_TIMESTAMP_TZ and CAST AS TIMESTAMP WITH LOCAL TIME ZONE in Oracle DB

I have an Oracle 11g database and I'm trying to experiment with how DST is handled with TIMESTAMP datatypes (especially ones created from incoming data that doesn't have a time zone included). I'm seeing a difference in behavior when using TO_TIMESTAMP_TZ() vs CAST(DATE as TIMESTAMP WITH LOCAL TIME ZONE) that I can't explain. I would expect that the resulting datatype is a zoned timestamp regardless of how it is created and any operation on it would be identical but it does not appear that this is the case.
Any idea why when using the CAST option the "extra" hour created by the Fall DST change isn't being taken into account in the INTERVAL math? I would expect both rows of the query below to be identical.
Query:
select to_timestamp_tz('11/1/2015 1:00 AM US/Pacific', 'MM/DD/YYYY HH:mi AM TZR') + interval '2' hour as DST_PLUS_2, -- this is a post DST jump time
to_timestamp_tz('11/1/2015 12:59 AM US/Pacific', 'MM/DD/YYYY HH:mi AM TZR') + interval '2' hour as PRE_DST_PLUS_2, -- this is a pre DST jump time
to_char(to_timestamp_tz('11/1/2015 1:00 AM US/Pacific', 'MM/DD/YYYY HH:mi AM TZR'), 'TZR') as TZR
from dual
union all
select cast(to_date('11/1/2015 1:00 AM', 'MM/DD/YYYY HH:mi AM') as timestamp with local time zone) + interval '2' hour as DST_PLUS_2,
cast(to_date('11/1/2015 12:59 AM', 'MM/DD/YYYY HH:mi AM') as timestamp with local time zone) + interval '2' hour as PRE_DST_PLUS_2,
to_char(cast(to_date('11/1/2015 1:00 AM', 'MM/DD/YYYY HH:mi AM') as timestamp with local time zone), 'TZR') as TZR
from dual;
Results:
DST_PLUS_2 PRE_DST_PLUS_2 TZR
01-NOV-15 03.00.00.000000000 AM US/PACIFIC 01-NOV-15 01.59.00.000000000 AM US/PACIFIC US/PACIFIC
01-NOV-15 03.00.00.000000000 AM US/PACIFIC 01-NOV-15 02.59.00.000000000 AM US/PACIFIC US/PACIFIC
It looks like this comes down to the fact that TO_TIMESTAMP_TZ attempts to infer the TZD element of the TIMESTAMP from the date while CAST AS TIMESTAMP WITH LOCAL TIME ZONE will take the current TZD of the database regardless of when the date is. Or they just have different default behaviors for picking which of the 1AM times (pre or post time change) to choose. This difference in behavior is causing the resulting hour to be different by one.
Thanks ruudvan!
Query:
select to_char(to_timestamp_tz('11/1/2015 1:00 AM US/Pacific', 'MM/DD/YYYY HH:mi AM TZR'), 'TZD') as TZD_TO_TS_TZ_1,
to_char(cast(to_date('11/1/2015 1:00 AM', 'MM/DD/YYYY HH:mi AM') as timestamp with local time zone), 'TZD') as TZD_CAST_1,
to_char(to_timestamp_tz('11/1/2015 12:00 AM US/Pacific', 'MM/DD/YYYY HH:mi AM TZR'), 'TZD') as TZD_TO_TS_TZ_12,
to_char(cast(to_date('11/1/2015 12:00 AM', 'MM/DD/YYYY HH:mi AM') as timestamp with local time zone), 'TZD') as TZD_CAST_12
from dual;
Results:
TZD_TO_TS_TZ_1 TZD_CAST_1 TZD_TO_TS_TZ_12 TZD_CAST_12
PST PDT PDT PDT
Data type TIMESTAMP WITH TIME ZONE stores the time zone information. When you insert 11/1/2015 1:00 AM US/Pacific then that is what is stored and that is what you get when you select it.
Data type TIMESTAMP WITH TIME LOCAL ZONE also stores time zone information. However, the value is always shown in current user session time zone SESSIONTIMEZONE. In principle Oracle put the value always in ({TIMESTAMP WITH TIME ZONE} value) AT TIME ZONE SESSIONTIMEZONE
DATE does not store any time zone information. If you run CAST({DATE value} as timestamp with local time zone) then Oracle runs basically FROM_TZ({DATE value}, SESSIONTIMEZONE) as timestamp with local time zone). I.e. it attaches the current user session time zone (which could be different to US/Pacific) to DATE value and then it converts the time zone, if required.
So the result of your query really depends on your current session timezone SESSIONTIMEZONE. Note, this might be US/Pacific or +07:00 / +08:00. If it is set to US/Pacific then daylight saving times are taken into account. For UTC offsets like +07:00 or +08:00 the time zones are fixes, i.e. daylight saving times are not considered.

Oracle SQL: convert UTC to CST

I would like to convert UTC date/time to local CST.
The below function works however it gives 6 hours difference when there should only be 5 hours (until day light saving on 11/2/2014).
CAST((FROM_TZ(CAST(utc_date AS TIMESTAMP),'UTC') AT TIME ZONE 'CST') AS DATE) cst_date
also tried a variation
to_date(to_char((from_tz(to_timestamp(to_char(utc_date, 'YYYY-MM-DD HH24:MI:SS'), 'YYYY-MM-DD HH24:MI:SS') ,'UTC')
at time zone 'CST'),'YYYY-MM-DD HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS') as cst_date,
Using the "US/Central" as the target timezone seems to produce the right result.
select from_tz(CAST ('15-oct-2014' AS TIMESTAMP),'GMT') at TIME ZONE 'US/Central' with_daylight_savings,
from_tz(CAST ('15-nov-2014' AS TIMESTAMP),'GMT') at TIME ZONE 'US/Central' without_daylight_savings
from dual;
WITH_DAYLIGHT_SAVINGS WITHOUT_DAYLIGHT_SAVINGS
--------------------------------------------------------------------------------------
14-OCT-14 07.00.00.000000000 PM US/CENTRAL 14-NOV-14 06.00.00.000000000 PM US/CENTRAL
Use timezone region instead of timezone abbr ('CST'). You may find the desired timezone here:
SELECT * from v$timezone_names where tzabbrev = 'CST';
Maybe you need 'CST6CDT' instead of 'CST'
Maybe a stupid approach, but what do you get from this query?
SELECT
TO_CHAR((TIMESTAMP '2014-01-01 00:00:00' + LEVEL * INTERVAL '1' DAY) AT TIME ZONE 'America/Chicago', 'yyyy-mm-dd hh24:mi TZH:TZM') AS dst,
TO_CHAR((FROM_TZ(CAST(DATE '2014-01-01' AS TIMESTAMP), 'UTC') + LEVEL * INTERVAL '1' DAY) AT TIME ZONE 'America/Chicago', 'yyyy-mm-dd hh24:mi TZH:TZM') AS dst
FROM dual
CONNECT BY LEVEL <= 365;
Is it as expected?

convert time zone sql with string datetime

I have a time in the format: DD-mon-RR HH.MI.SS.FF AM/PM in UTC time. I'd like to convert this to another time zone, but am having some trouble. Below is my code, but Oracle SQL Developer is saying date format not recognized.
Select From_Tz(Cast(To_Date('17-FEB-14 04.00.00.000000000 PM',
'DD-mon-RR HH.MI.SS.FF AM') As Timestamp), 'UTC')
AT TIME ZONE 'America/New_York' as "Local Time"
FROM DUAL;
I believe the format you need is DD-MON-YY HH.MI.SS.FF9 AM. See this reference.