获取给定时间戳和TZ名称的TZ缩写

时间:2016-09-13 14:14:04

标签: sql postgresql datetime timezone

在转换timestamptz类型的列后,是否可以获得正确的TZ缩写

我要追求的是,​​例如,显示 “2016-06-16 16:00:00-04”在“US / Pacific”时区中,目标TZ缩写。 我可以轻松搞定:

06/16/2016 01:00 pm

但我无法理解:

06/16/2016 01:00 pm PDT

转换后,timestamptz变为timestamp without timezoneto_char说明符'TZ'变得毫无意义......

这是我尝试过的一个例子:

SELECT
    scheduled_dt                                                                           AS scheduled_dt
  , to_char(scheduled_dt, 'TZ')                                                            AS scheduled_dt_orig_tz  
  -- correct value, but missing TZ  
  , timezone('US/Pacific', scheduled_dt)                                                   AS schedules_dt_converted_tz
  , to_char(timezone('US/Pacific', scheduled_dt), 'MM/DD/YYYY HH:MI pm')                   AS scheduled_dt_converted_tz_localized
   -- after conversion TZ is lost
  , to_char(timezone('US/Pacific', scheduled_dt), 'MM/DD/YYYY HH:MI pm TZ')                AS scheduled_dt_converted_tz_localized_missing_tz
  -- with cast, wrong TZ is displayed 
  , to_char(timezone('US/Pacific', scheduled_dt)::timestamptz, 'MM/DD/YYYY HH:MI pm TZ')   AS scheduled_dt_converted_tz_localized_wrong_tz
FROM orders
LIMIT 5  

和样本输出:

"scheduled_dt","scheduled_dt_orig_tz","schedules_dt_converted_tz","scheduled_dt_converted_tz_localized","scheduled_dt_converted_tz_localized_missing_tz","scheduled_dt_converted_tz_localized_wrong_tz"
"2016-06-16 16:00:00-04","EDT","2016-06-16 13:00:00","06/16/2016 01:00 pm","06/16/2016 01:00 pm ","06/16/2016 01:00 pm EDT"
"2014-07-15 08:00:00-04","EDT","2014-07-15 05:00:00","07/15/2014 05:00 am","07/15/2014 05:00 am ","07/15/2014 05:00 am EDT"
"2012-11-27 10:15:00-05","EST","2012-11-27 07:15:00","11/27/2012 07:15 am","11/27/2012 07:15 am ","11/27/2012 07:15 am EST"
"2011-03-02 08:30:00-05","EST","2011-03-02 05:30:00","03/02/2011 05:30 am","03/02/2011 05:30 am ","03/02/2011 05:30 am EST"
"2016-02-12 14:23:09-05","EST","2016-02-12 11:23:09","02/12/2016 11:23 am","02/12/2016 11:23 am ","02/12/2016 11:23 am EST"

2 个答案:

答案 0 :(得分:4)

不,因为timestamptz(又名timestamp with time zoneisn't really a timestamp with a time zone,就存储的内容而言......您提供时间戳和时区,在内部,它只是存储为UTC值。

听起来基本上你应该将目标时区与时间戳一起存储在一个单独的字段中。

答案 1 :(得分:3)

您无法从timestamptimestamptz中提取时区(名称或缩写),因为它根本就不存在。详细解释:

由于您使用全名存储目标TZ,因此可能从系统视图pg_timezone_names中提取关联的时区缩写(基于内部函数{{1} })。

pg_timezone_names()

然而per documentation:

  

显示的信息是根据SELECT abbrev FROM pg_timezone_names WHERE name = 'US/Pacific'; abbrev -------- PDT 的当前值计算的。

这意味着,您将在夏季获得 PDT ,在冬季获得 PST ,根据当前时间 根据您要显示的时间戳。

不是您需要的解决方案,抱歉。

function definition of pg_timezone_names in the PostgreSQL source code可能会为您提供有关如何实现自己的C函数的建议。

相关: