【问题标题】:Oracle EDT/EST time to GMT conversionOracle EDT/EST 时间到 GMT 转换
【发布时间】:2015-07-27 15:08:06
【问题描述】:

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

转换应该基于数据库日期而不是服务器本地 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". 

和往年一样。 有解决办法吗?

【问题讨论】:

  • 您是否正在寻找:some_date_column at time zone 'GMT'?
  • 什么是 SOME_DATE_COLUMN?
  • 我尝试选择 AT TIME ZONE dbtimezone,但我总是得到 -05:00。我想我会在 12 月运行它,它会返回 -04:00。现在有没有办法返回与结果集中日期相关的正确偏移量?
  • DBTIMEZOME 是一个固定值,通常不会改变(即使在夏季/冬季也不会改变)。您的列的数据类型是什么?
  • some_date_column 是表中定义为日期的某些列。当您选择对我们隐藏您的表定义时,我必须想出一些名称。

标签: oracle timestamp


【解决方案1】:

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

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 指定其原始区域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-26
    • 2023-03-20
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 2012-06-15
    • 2014-05-18
    相关资源
    最近更新 更多