Reputation: 11417
I have a simple select query such as below but I noticed I am getting back the regional times. How can I convert to UTC in my select statment?
select myTimeStamp, MyName, MyBranch from tableA
Result: '27/03/2014 15:15:26' 'john', 'london'
I have tried using sys_extract_utc (myTimeStamp) but I have the error
sql command not properly ended
The column myTimestamp
is of type 'date'.
Upvotes: 20
Views: 113686
Reputation: 31666
Starting from Oracle 19c, a new function is introduced which is TO_UTC_TIMESTAMP_TZ
The SQL function TO_UTC_TIMESTAMP_TZ takes an ISO 8601 date format string as the varchar input and returns an instance of SQL data type TIMESTAMP WITH TIMEZONE. It normalizes the input to UTC time (Coordinated Universal Time, formerly Greenwich Mean Time). Unlike SQL function TO_TIMESTAMP_TZ , the new function assumes that the input string uses the ISO 8601 date format, defaulting the time zone to UTC 0.
select TO_UTC_TIMESTAMP_TZ ( to_char(sysdate,'yyyy-mm-dd"T"HH:MI:SS') ) as utc
from dual;
UTC
31-MAR-19 05.45.36.000000 AM +00:00
Upvotes: 0
Reputation: 3135
Depending on the type, there are a couple of gotchas with regard to what time zone Oracle is converting from depending on what the data type of myTimestamp
is.
It Just Works™. a_horse_with_no_name has the right answer here.
it is implicitly cast to timestamp with time zone, then It Just Works™. Again, a_horse_with_no_name is right here.
While it too is implicitly cast to timestamp with time zone, the time zone that gets assigned by default is the session time zone (as opposed to the database time zone).
myTimestamp at local
.from_tz
function to explicitly build a value with an explicit time zone other than that of your session.Trying to do any of the above to date will fail as you described:
myTimestamp at time zone 'UTC'
from_tz(myTimestamp, 'America/New_York')
The solution here is to cast the date to a timestamp first:
select from_tz(cast(myTimestamp as timestamp), 'America/New_York') from tableA
The following script illustrates the behavior. Note that on my system, dbtimezone
is US/Central, and sessiontimezone
is GMT-05:00.
I also use to_char
to convert the output as I have found some tools will alter the result timestamp in subtle ways, particularly if they don't have good timestamp support (this is rare nowadays, but still potentially a problem).
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'
/
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR'
/
select dbtimezone
,sessiontimezone
,to_char(timestamp '2017-01-01 06:00:00') as ts
,to_char(timestamp '2017-01-01 06:00:00' at local) as ts_at_local
,to_char(timestamp '2017-01-01 06:00:00' at time zone dbtimezone) as ts_at_db
,to_char(timestamp '2017-01-01 06:00:00' at time zone sessiontimezone) as ts_at_session
from dual
/
The output on my system is as follows (reformatted as columnar for readability):
DBTIMEZONE US/Central
SESSIONTIMEZONE -05:00
TS 2017-01-01 06:00:00
TS_AT_LOCAL 2017-01-01 06:00:00 -05:00
TS_AT_DB 2017-01-01 05:00:00 US/CENTRAL
TS_AT_SESSION 2017-01-01 06:00:00 -05:00
Upvotes: 11
Reputation:
select cast(mytimestamp as timestamp) at time zone 'UTC',
MyName,
MyBranch
from tableA
Because mytimestamp
is in fact a date
not a timestamp you need to cast it. Doing that makes Oracle assume that the information stored in mytimestamp
is in the time zone of the server -if that isn't the case you need to use Madhawas' solution.
Upvotes: 24
Reputation: 391
You need to know your time zone for this;
SELECT myTimeStamp, from_tz(myTimeStamp, 'America/New_York') AT TIME ZONE 'UTC' utc FROM dual;
Upvotes: 7