Oracle EDT / EST时间转换为GMT

时间:2015-07-27 15:08:07

标签: oracle timestamp

我们在oracle存储的所有日期都在EDT(夏季)和EST(冬季)。我需要一种方法将该日期转换为UTC / GMT。

转换应该基于db日期而不是服务器本地TZ。 换句话说,如果结果集中的日期介于:

之间
"11/02/2014 02:00:00" ---> "03/08/2015 01:59:59": TZ offset = "-0500"
"03/08/2015 02:00:00" ---> "11/01/2015 01:59:59": TZ offset = "-0400". 

前几年也一样。 有解决方案吗?

1 个答案:

答案 0 :(得分:0)

假设some_date_column实际上是一个日期列,那么您可以使用强制转换(从日期到时间戳)将其转换为带时区的时间戳,将the from_tz function转换为具有EST / EDT更改的区域定义:

with t (some_date_column) as (
  select to_date('11/02/2014 02:00:00', 'MM/DD/YYYY HH24:MI:SS') from dual
  union all
  select to_date('03/08/2014 01:59:59', 'MM/DD/YYYY HH24:MI:SS') from dual
  union all
  select to_date('03/08/2015 03:00:00', 'MM/DD/YYYY HH24:MI:SS') from dual
  union all
  select to_date('11/01/2015 00:59:59', 'MM/DD/YYYY HH24:MI:SS') from dual
  union all
  select to_date('11/01/2015 01:59:59', 'MM/DD/YYYY HH24:MI:SS') from dual
  union all
  select to_date('11/02/2015 02:00:00', 'MM/DD/YYYY HH24:MI:SS') from dual
)
select t.some_date_column,
  cast(t.some_date_column as timestamp) as some_timestamp,
  from_tz(cast(t.some_date_column as timestamp), 'America/New_York')
    as some_timestamp_tz
from t;

SOME_DATE_COLUMN    SOME_TIMESTAMP      SOME_TIMESTAMP_TZ         
------------------- ------------------- ---------------------------
11/02/2014 02:00:00 11/02/2014 02:00:00 11/02/2014 02:00:00 -05:00 
03/08/2014 01:59:59 03/08/2014 01:59:59 03/08/2014 01:59:59 -05:00 
03/08/2015 03:00:00 03/08/2015 03:00:00 03/08/2015 03:00:00 -04:00 
11/01/2015 00:59:59 11/01/2015 00:59:59 11/01/2015 00:59:59 -04:00 
11/01/2015 01:59:59 11/01/2015 01:59:59 11/01/2015 01:59:59 -05:00 
11/02/2015 02:00:00 11/02/2015 02:00:00 11/02/2015 02:00:00 -05:00 

这与你问题中的范围并不完全一致。当你从EST转到EDT时没有02:00,所以我在演示CTE中使用了03:00;当你从EDT转到EST的另一条路时,01:00到02:00之间的时间间隔(有点)重复,那个小时的平时偏移是不明确的,Oracle选择将其视为-05 :00而不是-04:00。

如果您希望UTC相当于EST / EDT时间,那么您可以使用at time zone,并可选择强制转换为日期:

...
select t.some_date_column,
  from_tz(cast(t.some_date_column as timestamp), 'America/New_York')
    at time zone 'UTC' as utc_timestamp_tz,
  cast(from_tz(cast(t.some_date_column as timestamp), 'America/New_York')
    at time zone 'UTC' as date) as utc_date
from t;

SOME_DATE_COLUMN    UTC_TIMESTAMP_TZ            UTC_DATE          
------------------- --------------------------- -------------------
11/02/2014 02:00:00 11/02/2014 07:00:00 +00:00  11/02/2014 07:00:00
03/08/2014 01:59:59 03/08/2014 06:59:59 +00:00  03/08/2014 06:59:59
03/08/2015 03:00:00 03/08/2015 07:00:00 +00:00  03/08/2015 07:00:00
11/01/2015 00:59:59 11/01/2015 04:59:59 +00:00  11/01/2015 04:59:59
11/01/2015 01:59:59 11/01/2015 06:59:59 +00:00  11/01/2015 06:59:59
11/02/2015 02:00:00 11/02/2015 07:00:00 +00:00  11/02/2015 07:00:00

如果原始列是时间戳(没有时区信息)而不是日期,那么您可以跳过从日期到时间戳的第一个强制转换,但仍然使用from_tz来指定它的原始区域。