在 postgresql 中将 GMT 转换为 CST

Converting GMT to CST in postgresql

我目前正在处理具有 GMT 时间戳的原始数据,我想将它们转换为 CST。我正在尝试使用 cast 函数更改时间戳,但它不起作用 - 时间不受影响。我在 postgresql 中读到的关于时区的大部分内容都假设默认时区是 UTC,所以我不确定当我尝试转换的数据是 GMT 时是否需要不同的语法。非常感谢任何帮助!

WITH RECURSIVE "child" AS (
    SELECT "ConsultantDisplayID",
           "JoinDate",
           "ParentPersonDisplayID"
    FROM "public"."flight_export_consultant"
    WHERE "ConsultantDisplayID" = '4019'
UNION 
    SELECT c."ConsultantDisplayID", 
           CAST(c."JoinDate" at time zone 'america/chicago' as timestamp) as "JoinDate"
           c."ParentPersonDisplayID"
    FROM "public"."flight_export_consultant" AS c 
    JOIN "child" AS cd 
    ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
    
"sponsor" AS (
    SELECT 
        "child".*,
        c1."ConsultantDisplayID",
        Cast(c."JoinDate" at time zone 'america/chicago' as timestamp) as "Sponsor JoinDate"
    FROM "public"."flight_export_consultant" AS c1
    LEFT JOIN "child" 
    ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")  

SELECT * FROM "sponsor"

鉴于 JoinDatetimestamp 类型,这应该是适合您的情况的一个很好的解决方法,因为我们已经确定 JoinDate 中的值是 timestamp 类型代表 UTC/GMT 个时间戳,而你的服务器不在 UTC/GMT。理想的解决方案是使用 timestamptz 列。

这里的技巧是将 JoinDate 转换为 text,向其附加一个 z 使其成为 UTC,然后将其转换为 timestamptz。完成后,您可以使用 at time zone 'us/chicago' 为您进行转换。

WITH RECURSIVE "child" AS (
    SELECT "ConsultantDisplayID",
           "JoinDate",
           "ParentPersonDisplayID"
    FROM "public"."flight_export_consultant"
    WHERE "ConsultantDisplayID" = '4019'
UNION 
    SELECT c."ConsultantDisplayID", 
           "JoinDate",
           c."ParentPersonDisplayID"
    FROM "public"."flight_export_consultant" AS c 
    JOIN "child" AS cd 
    ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
    
"sponsor" AS (
    SELECT 
        "child".*,
        c1."ConsultantDisplayID",
        c."JoinDate" as "Sponsor JoinDate"
    FROM "public"."flight_export_consultant" AS c1
    LEFT JOIN "child" 
    ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")  

SELECT "ConsultantDisplayID", 
       ("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "JoinDate",
       "ParentPersonDisplayID",
       "ConsultantDisplayID",
       ("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "Sponsor JoinDate"
FROM "sponsor";

正如@Mike Organek 指出的那样,timestamp 类型的字段假定输入时为当地时间。因此,您需要确定的第一件事是输入日期的来源以及它们是否实际输入为 GMT。目前假设他们是你可以做以下事情:

select 'September 24, 2018, 4:01PM'::timestamp at time zone 'utc' at time zone 'america/chicago';
      timezone       
---------------------
 09/24/2018 11:01:00

-- Or if you want to stick to GMT

select 'September 24, 2018, 4:01PM'::timestamp at time zone 'gmt' at time zone 'america/chicago';
      timezone       
---------------------
 09/24/2018 11:01:00

基本上你是 'anchoring' 在 UTC/GMT 的时间戳,然后转换为 'america/chicago'。换句话说,复制 timestamptz 字段的作用。