我想知道如何从时区偏移量中获取时区名称。例如,如果我"GMT-07_(PDT)
,我应该返回America/Los_Angeles
。同样,GMT+5.5_(INDIA)
应返回Asia/Kolkata
,GMT+09_(JAPAN)
应返回Asia/Tokyo
。
我必须在Oracle中实现这一点。
答案 0 :(得分:2)
一些字符串操作和以下内容的组合应该让你关闭
TZ_OFFSET()
,它根据时区区域名称V$TIMEZONE_NAMES
,其中包含时区和缩写首先,您需要提取提供的偏移量:
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。