如何将“GMT + 5.5_(INDIA)”转换为时区“Asia / Kolkata”

时间:2017-12-27 12:32:37

标签: oracle oracle11g timezone

我想知道如何从时区偏移量中获取时区名称。例如,如果我"GMT-07_(PDT),我应该返回America/Los_Angeles。同样,GMT+5.5_(INDIA)应返回Asia/KolkataGMT+09_(JAPAN)应返回Asia/Tokyo

我必须在Oracle中实现这一点。

2 个答案:

答案 0 :(得分:2)

一些字符串操作和以下内容的组合应该让你关闭

首先,您需要提取提供的偏移量:

select regexp_replace( 'GMT+5.5_(INDIA)'
                     , '[[:alpha:]]{3}(-|\+)(\d+)(\.(\d+))?.*'
                     , '\1\2\3')
  from dual

然后,您需要将其转换为正确的格式。假设正则表达式为您提供了名为s的东西:

with setup as (
select to_number(s) as n from ...
       )
    select case when n < 0 then '-' else '+' end 
           || lpad(trunc(n), 2, '0') 
           || ':' 
           || lpad((n - trunc(n)) * 60, 2, '0') as offset
      from dual

最后,您可以使用此选项查询我们的视图,使用TZ_OFFSET返回所有有效时区区域。

select tzname
  from v$timezone_names
 where tzoffset(tzname) = :offset

如果你想选择一个时区,你需要创建一些额外的逻辑来描述你想要选择的那个。

在单个查询中,这看起来很难看,但就像

with strip_characters as (
select to_number(regexp_replace( 'GMT+5.5_(INDIA)'
                               , '[[:alpha:]]{3}(-|\+)(\d+)(\.(\d+))?.*'
                               , '\1\2\3'))
  from dual
       )
, setup as (
select case when n < 0 then '-' else '+' end 
       || lpad(trunc(n), 2, '0') 
       || ':' 
       || lpad((n - trunc(n)) * 60, 2, '0') as offset
  from strip_characters
       )
select t.tzname
  from v$timezone_names t
  join setup s
 where tzoffset(t.tzname) = s.offset

答案 1 :(得分:0)

对于所有情况,您无法以可靠的方式提出要求。任何企图都会偏向特定的世界观。

例如,您提供了GMT-07_(PDT)并说它应该是America/Los_Angeles。这意味着美国的时区标识符在某种程度上更重要。所有以下规范区域标识符均使用太平洋夏令时和GMT-07:

  • America/Los_Angeles(美国)
  • America/Tijuana(墨西哥)
  • America/Vancouver(加拿大)
  • America/Dawson(加拿大)
  • America/Whitehorse(加拿大)

即使以美国为中心的世界观,并限制于现代,它仍然无法发挥作用。考虑另一个例子:GMT-07_(MST)。那是America/Denver还是America/Phoenix?丹佛代表一个在-7和-6之间转换的区域,用于夏令时,但凤凰代表的区域在-7全年无法夏令时。

这些是相对简单的例子。考虑一下你是否GMT+01_(CET)。与之抗衡的差异数量有很多要列出。

同时考虑并非每个时区都有一个有意义的缩写,并且时区缩写不一致(例如:HST与HAST)并且通常不明确(例如:CST)。

通常,可以从特定时间点的时区标识符确定偏移量(有时是缩写),但反向无法实现。

另见&#34;时区!=偏移&#34;在the timezone tag wiki