1. Assuming it's a plain timestamp with no time zone information, you can:
Use from_tz to add the hour offset to the daets
Return this at time zone 'UTC' to convert it ot the equivalent UTC time:
alter session set NLS_TIMESTAMP_TZ_FORMAT = 'DD-MON HH24:MI TZR';
select from_tz ( timestamp'2020-01-01 00:00:00', 'US/Eastern' ) first_jan_et,
from_tz ( timestamp'2020-07-07 00:00:00', 'US/Eastern' ) seventh_jul_et,
from_tz ( timestamp'2020-01-01 00:00:00', 'US/Eastern' ) at time zone 'UTC' first_jan_utc,
from_tz ( timestamp'2020-07-07 00:00:00', 'US/Eastern' ) at time zone 'UTC' seventh_jul_utc
from dual;
FIRST_JAN_ET
---------------------------------------------------------------------------
SEVENTH_JUL_ET
---------------------------------------------------------------------------
FIRST_JAN_UTC
---------------------------------------------------------------------------
SEVENTH_JUL_UTC
---------------------------------------------------------------------------
01-JAN 00:00 US/EASTERN
07-JUL 00:00 US/EASTERN
01-JAN 05:00 UTC
07-JUL 04:00 UTC
2. It depends on how you plan on handling this. If you store the new values:
Without time zone information, you'll have to do the conversion in the client.
With time zone, you'll have to add the time zone in the client
With local time zone, the database will normalize the values to the database time zone
With the final option, the value displayed will change based on the client's time zone settings:
select dbtimezone, sessiontimezone from dual;
DBTIME SESSIONTIMEZONE
------ ---------------------------------------------------------------------------
+00:00 Europe/London
create table t (
c1 int,
c2 timestamp,
c3 timestamp with time zone,
c4 timestamp with local time zone
);
insert into t
values (
1,
timestamp'2020-09-14 00:00:00',
timestamp'2020-09-14 00:00:00',
timestamp'2020-09-14 00:00:00'
);
alter session set time_zone = 'US/Eastern';
insert into t
values (
2,
timestamp'2020-09-14 00:00:00',
timestamp'2020-09-14 00:00:00',
timestamp'2020-09-14 00:00:00'
);
select * from t;
C1 C2 C3 C4
-- ------------------------------ ------------------------------ ------------------------------
1 14-SEP-20 12.00.00.000000 AM 14-SEP 00:00 EUROPE/LONDON 13-SEP-20 07.00.00.000000 PM
2 14-SEP-20 12.00.00.000000 AM 14-SEP 00:00 US/EASTERN 14-SEP-20 12.00.00.000000 AM
alter session set time_zone = 'Europe/London';
select * from t;
C1 C2 C3 C4
-- ------------------------------ ------------------------------ ------------------------------
1 14-SEP-20 12.00.00.000000 AM 14-SEP 00:00 EUROPE/LONDON 14-SEP-20 12.00.00.000000 AM
2 14-SEP-20 12.00.00.000000 AM 14-SEP 00:00 US/EASTERN 14-SEP-20 05.00.00.000000 AM
So it comes down to how you want to do this.
3. If you want to ensure backwards compatibility, you may need to do this.
Bear in mind that updating every row in the table could take a long time if the table has millions of rows or more. And that doing it all in one update will lock the rows for changes by every other session.
You could do this online using Edition-based redefinition.
Or if you want a faster way, you could use dbms_redefinition to do this.