我们正在讨论在postgres中存储时间戳的最佳方式。目前,所有时间戳都存储为+00,并且我们有一个与每个客户端相关联的时区。我们查找时区并转换发生事情的时间,这增加了复杂性,因为我们需要进行更多的连接和更复杂的查询。
另一种方法是连接到Postgres并设置连接的时区,它会将所有时间更改为该时区。
我的问题是在ANZ有4-5个时区。当我们尝试开具发票时,我们需要知道某些交易发生在哪一天,并且跨三个时区没有完美的解决方案。
我在考虑将时区包含在时间戳中以使其更容易- timestamp '1999-01-15 8:00:00 -8:00‘
我的印象是这是最好的做法,但有些人说这是一个坏主意。我们将在整个澳新银行有客户,我们需要为他们做准确的发票,什么是最好的解决方案和最优雅的?
干杯斯科特
发布于 2013-01-31 08:46:32
这里没有防弹的解决方案。
我的第一个建议是:永远不要依赖服务器的默认时区。
我的第二个建议:根据数据的(主要)语义在timestamp-timestamptz之间进行选择。
更详细地说:TIMESTAMP WITHOUT TIMEZONE (timestamp)和TIMESTAMP WITH TIMEZONE (timestamptz).是PostgresSQL的两个时间戳变体,它们的名称令人困惑实际上,既不存储时区,也不存储偏移量。这两种数据类型占用相同的宽度(4字节),并且它们的差异很细微-更糟糕的是,如果您没有完全理解它们,并且您的服务器更改了时区,可能会咬您一口。我的理智规则集是:
TIMESTAMP WITH TIMEZONE (timestamptz)来存储主要与“物理”时间相关的事件,对于这些事件,您主要希望查询event 1是否在event 2之前(与时区无关),或者计算时间间隔(以“物理单位”表示,例如秒;而不是以“民用”单位表示,如天-月等)。典型的例子是记录创建/修改时间--通常用单词"Timestamp".TIMESTAMP WITHOUT TIMEZONE (timestamp)来表示存储事件的相关信息是"civil time" (即,字段{year-month-day hour-min-sec}作为一个整体),并且查询涉及日历计算。在这种情况下,您只需在此处存储“本地时间”,即相对于某个未指定(无关、隐含或存储在其他地方)时区的日期-时间。第二个选项使您更容易查询“在‘2013-01-20’日发生的所有事件”(在每个相应的地区/国家/时区)-但更难查询“在参考事件之前(物理上)发生的所有事件”(除非我们知道它们在同一时区)。你来选吧。
如果您需要全部功能,但两者都不够,则需要将时区或偏移量存储在附加字段中。另一种选择是同时存储两个字段,这会浪费几个字节,但查询效率更高。
另请参见this answer。
发布于 2013-01-31 07:12:29
对于输入字段使用timestamptz (或标准SQL语法为timestamp with time zone ),然后可以使用时区或时间偏移量为每个插入设置一个自定义时间偏移量,以适合您的喜好。
示例…
CREATE TABLE "timetest"
(
"timestamp" timestamptz
);
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 PST');
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 Europe/Madrid');
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 Europe/Athens');
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 GMT+11');
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 GMT-11');
INSERT INTO "timetest" ("timestamp") VALUES ('2013-01-01 08:45:00 UTC');...and你的时间会相应地调整
SELECT * FROM "timetest"; -- note this may default to your timezone
------------------------
[timestamp]
------------------------
2013-01-01 16:45:00+00
2013-01-01 07:45:00+00
2013-01-01 06:45:00+00
2012-12-31 21:45:00+00
2013-01-01 19:45:00+00
2013-01-01 08:45:00+00
2013-01-01 08:45:00+00或者更好的做法是,尝试执行以下操作。
SELECT
"timestamp" AT TIME ZONE 'Australia/Sydney' AS "Sydney",
"timestamp" AT TIME ZONE 'Australia/Perth' AS "Perth"
FROM "timetest";
--------------------------------------------
[Sydney]..............[Perth]
--------------------------------------------
2013-01-02 03:45:00 - 2013-01-02 00:45:00
2013-01-01 18:45:00 - 2013-01-01 15:45:00
2013-01-01 17:45:00 - 2013-01-01 14:45:00
2013-01-01 08:45:00 - 2013-01-01 05:45:00
2013-01-02 06:45:00 - 2013-01-02 03:45:00
2013-01-01 19:45:00 - 2013-01-01 16:45:00最后,要了解数据库可用的时区列表,可以尝试:
SELECT * FROM pg_timezone_names ORDER BY utc_offset DESC; https://stackoverflow.com/questions/14615271
复制相似问题