php 设置PostgreSQL示例的时区

bis0qfac  于 2022-12-10  发布在  PHP
关注(0)|答案(3)|浏览(139)

我正在使用最新的Zend框架与PostgreSQL数据库进行通信。我的一些数据库表有一个now()字段添加了当前时间戳。但是,对于不同的请求,数据库连接的时区可能不同。
是否可以基于每个连接设置PostgreSQL数据库的时区?我知道您可以将驱动程序选项传递给Zend_Db的示例,所以我认为这就是诀窍。

jk9hmnmh

jk9hmnmh1#

首先,考虑数据类型timestamptztimestamp with time zone)而不是timestamptimestamp without time zone)。然后用户的时区就不重要了。now()返回timestamptz,您的问题源于将其强制为timestamp。请参阅:

  • 在Rails和PostgreSQL中完全忽略时区

“但我需要timestamp类型!"

如果您的连接与**可绑定到时区的数据库角色(登录)**发生关联,则PostgreSQL提供了一个简单的解决方案:

ALTER ROLE my_role SET TIMEZONE = '+1';

使用此角色启动的每个连接都将在其预设时区中自动运行(除非另有说明)。
请注意,quoting the manual
这只在登录时发生;执行SET ROLESET SESSION AUTHORIZATION不会导致设置新的配置值。
您可能希望使用 * 时区名称 * 而不是纯偏移量来遵循DST规则和其他对当地时间的政治操纵。更多信息:

  • 在Rails和PostgreSQL中完全忽略时区
    或者,您可以为您的登录创建一个查找表,在其中存储相应的时区(可能用于其他用途):
CREATE TABLE usertime(
  username text PRIMARY KEY  -- careful, "user" is a reserved word
, timezone text              -- ... but "timezone" is not
);

INSERT INTO usertime VALUES
  ('postgres', '+4')
, ('my_role' , '+3')
;

编写一个小型SQL函数:

CREATE FUNCTION f_user_ts()
  RETURNS timestamp
  LANGUAGE sql STABLE AS
$func$
SELECT now() AT TIME ZONE u.timezone
FROM   usertime u
WHERE  u.username = current_user
$func$;

现在,这将返回当前角色(用户)的本地时间戳:

SELECT f_user_ts();

更多信息

请参阅AT TIME ZONE构造的详细手册。以下两种语法变体都是有效的:

SET TIME ZONE TO 'UTC';
SET TIMEZONE TO 'UTC';

now() AT TIMEZONE foo;不是!它必须是:

SELECT now() AT TIME ZONE foo;

footext变量(或类似于上述函数中的列),包含时区偏移量、缩写或名称。您也可以直接提供字符串文字。

vcudknz3

vcudknz32#

在SQL中,

SET TIMEZONE TO 'America/New_York';

若要获取时区的名称,请使用

SELECT * 
FROM pg_timezone_names;
lrpiutwd

lrpiutwd3#

这只是一个很长的机会,但是如果您设置了所使用的角色的时区会怎么样呢?

ALTER ROLE my_db_user IN DATABASE my_database
    SET "TimeZone" TO 'UTC';

相关问题