如何附加时间间隔偏移量时间戳

时间:2019-05-20 22:39:29

标签: postgresql

我有3列 1)from_date。 (没有时区的时间戳) 2)to_date(没有时区的时间戳) 3)utc_offset(间隔)

预期输出: 假设我有这种格式的日期 2018-12-31T23:00:00,间隔为0 years 0 mons 0 days -5 hours 0 mins -0.00 secs

然后我想将日期显示为2018-12-31T23:00:00-05:00

当偏移量为0 years 0 mons 0 days +5 hours 0 mins +0.00 secs时 那么日期应为2018-12-31T23:00:00+05:00

当前解决方案:

select concat(cast('2019-02-28 23:59:59':: timestamp with time zone as 
timestamp(0))::text , coalesce(to_char('0 years 0 mons 0 days -5 hours 
0 mins 0.00 secs'::interval,'HH:MM') ,'00:00'))

这是给我返回正确的结果2019-02-28 23:59:59-05:00

但是当间隔改变时

 select concat(cast('2019-02-28 23:59:59':: timestamp with time zone 
 as 
 timestamp(0))::text , coalesce(to_char('0 years 0 mons 0 days +5 
 hours 
 0 mins 0.00 secs'::interval,'HH:MM') ,'00:00'))

那么结果是 2019-02-28 23:59:5905:00

当偏移量超前时,如何获得结果为2019-02-28 23:59:59+05:002019-02-28 23:59:59-05:00(当偏移量落后时)

2 个答案:

答案 0 :(得分:0)

这是个主意,但是没有办法将时间戳记存储为TIMESTAMP WITH TIMEZONE吗?

SELECT '2019-05-21 02:02:20'::timestamp at time zone a.abbrev 
FROM
(
    SELECT abbrev
    FROM pg_timezone_names 
    WHERE utc_offset = '-05:00:00'
    LIMIT 1
) a
;

timezone
2019-05-21 08:02:20+01

或作为功能:

CREATE OR REPLACE FUNCTION timestamp_tz(ts timestamp, off interval)
RETURNS SETOF timestamptz
AS $$
DECLARE
BEGIN
    RETURN QUERY
    SELECT ts AT TIME ZONE a.abbrev 
    FROM
    (
        SELECT abbrev
        FROM pg_timezone_names 
        WHERE utc_offset = off
        LIMIT 1
    ) a
    ;
END;
$$  LANGUAGE PLPGSQL;

答案 1 :(得分:0)

我同意J Spratt的观点,最好只存储带有时区的时间戳,尽管不可能单独从该时间戳创建偏移量。

这是可以执行此格式化的功能。基本上,将本地会话时区设置为偏移量并从此处设置格式。

create or replace function format_date(start timestamp, utc_offset interval)
returns text
set timezone from current
AS
$$
DECLARE
  out text;
BEGIN
  EXECUTE 'SET local time zone INTERVAL ' || quote_literal(utc_offset) || ' HOUR TO MINUTE';
  select to_char(start at time zone utc_offset, 'YYYY-MM-DD HH24:MI:SSOF') into out;
  RETURN out;
END
$$ LANGUAGE plpgsql;
# select format_date('2018-12-31T23:00:00'::timestamp, interval '+5 hours');
      format_date
------------------------
 2018-12-31 23:00:00+05
(1 row)
# select format_date('2018-12-31T23:00:00'::timestamp, interval '-5 hours');
      format_date
------------------------
 2018-12-31 23:00:00-05
(1 row)