【问题标题】:Postgresql select output date with missing timezone offsetPostgresql 选择缺少时区偏移的输出日期
【发布时间】:2018-10-01 08:39:33
【问题描述】:

我很难使用 postgresql 和时区。

Postgresql 服务器位于 UTC 时区。 我想执行一个查询,返回具有时区偏移的另一个时区中的日期。

我可以执行返回时区日期的查询,但 我缺少时区偏移量

base=# SET timezone to 'utc';
SET
base=# select now();
             now              
------------------------------
 2018-04-20 14:58:22.68038+00
(1 row)

base=# SET timezone to 'Europe/Paris';
SET
base=# select now();
              now              
-------------------------------
 2018-04-20 16:58:29.614383+02
(1 row)


base=# SET timezone to 'utc';
SET
base=# select now() AT TIME ZONE 'Europe/Paris';
          timezone          
----------------------------
 2018-04-20 16:59:03.146917   -- missing timezone offset here
(1 row)

预期结果

base=# SET timezone to 'utc';
SET
base=# select now() AT TIME ZONE 'Europe/Paris'; --I'm missing something here, I guess
          timezone          
----------------------------
 2018-04-20 16:59:03.146917+02   -- That's what I want
(1 row)

你知道怎么做吗?

谢谢

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    如果你使用AT TIME ZONE,PG会返回一个没有时区的时间戳。如果您将其转换回带有时区的时间戳,您会得到预期的结果:

    SELECT (NOW() AT TIME ZONE 'Europe/Paris')::TIMESTAMPTZ;

    结果:

    2018-04-20 18:15:26.165+02


    如何在不设置时区的情况下获得 +02?这就是问题所在:NOW() AT TIME ZONE 'Europe/Paris' 返回指定时区中的当前时间(没有偏移量),并将其转换回TIMESTAMPTZ 会根据 UTC 为您提供当前时区(您的 PG 会话)的偏移量。由于 'Europe/Paris' 与 UTC 相比为 +02,如果您将时区设置为 'Europe/Paris',则在 TIMESTAMPTZ 中获得的偏移量为 +02。如果您当前的时区设置为 UTC,则您的偏移量为 +00。

    无论您的 PG 会话的时区设置如何,如何在不明确设置时区的情况下获取偏移量?我想有一种更好的方法来获取偏移量,但是在不知道的情况下,这是一种方法:计算偏移量,格式化它,将其附加到没有时区的时间戳。

    SELECT (NOW() AT TIME ZONE 'Europe/Paris')::TEXT || TO_CHAR(EXTRACT(hour FROM NOW() AT TIME ZONE 'Europe/Paris' - NOW() AT TIME ZONE 'UTC'), 'FMSG00')

    结果:2018-04-21 15:12:42.658+02,无论当前时区如何,我都会得到相同的结果。

    【讨论】:

    • 谢谢,只有当我们使用 set time zone 'Europe/Paris'; 时它才会给出预期的结果然后我们只需要使用:`SELECT (NOW())::TIMESTAMPTZ;` 来获得:2018-04-21 13:31:12.088679+02。我想在不使用SET TIME ZONE 'Europe/Paris'; 明确设置时区的情况下得到这个结果
    【解决方案2】:
    • 某些时区有 30 或 45 分钟的偏移量。 使用TO_CHAR(EXTRACT(hour FROM NOW() AT TIME ZONE 'Europe/Paris' - NOW() AT TIME ZONE 'UTC') 排除此用例。

    • 您是否考虑在专用函数中使用SET LOCAL TIME ZONE 'Europe/Paris';?根据文档:

    如果在对同一变量有 SET 选项的函数中使用 SET LOCAL(请参阅 CREATE FUNCTION),则 SET LOCAL 命令的效果会在函数退出时消失

    其他回复似乎符合您的要求:How to convert timestamp field to ISO 8601 string in a given time zone?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 2023-03-16
      • 2015-08-03
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      相关资源
      最近更新 更多