如何在PostgreSQL时间戳列中插入通用协调时间?

如何在PostgreSQL时间戳列中插入通用协调时间?,postgresql,timestamp,Postgresql,Timestamp,我的数据库和客户目前在美国/纽约,但可以移动到任何地方 SHOW TIMEZONE; -- America/New_York CREATE TABLE times ( t TIMESTAMP WITHOUT TIME ZONE ); INSERT INTO times VALUES (NOW()), (NOW() AT TIME ZONE 'UTC'); SELECT t FROM times; -- 2017-06-13 14:53:17.766969 -- 2017-06-

我的数据库和客户目前在美国/纽约,但可以移动到任何地方

SHOW TIMEZONE; -- America/New_York

CREATE TABLE times (
  t TIMESTAMP WITHOUT TIME ZONE
);

INSERT INTO times VALUES
  (NOW()),
  (NOW() AT TIME ZONE 'UTC');

SELECT t FROM times;
-- 2017-06-13 14:53:17.766969
-- 2017-06-13 18:53:17.766969
这是出乎意料的。我认为我的SELECT将为两条记录返回相同的值

当我在t列中插入当前时间时,我希望它表示任何时区中的当前时间,无论数据库是否将基础值存储为当前时间UTC。这样,无论数据库在哪个时区运行,或者客户端在哪个时区运行,每个人都可以在统一协调的固定时间点上达成一致


插入记录的正确方法是什么,这样世界上的每个人都知道我引用的是“UTC”时间?

首先,SELECT似乎假设没有时区字段的时间戳存储在本地时区中。尝试设置时区“UTC+”。SELECT的输出不变,即,如果未存储时区,则时间戳并不表示UTC

如果字段类型为timestamp with time zone,SELECT将正确地将输出转换为当前时区

因此,当你说在时区“UTC”时,你将时间转换为UTC,然后放弃时区,使Postgres认为你在处理本地时间

您可以通过添加另一个时区“UTC”条款重新引入UTC时区:


一句话:如果您坚持在没有时区的情况下工作,我会始终使用带时区的时区,或者始终将数据库时区设置为UTC。这两种类型的存储大小似乎是相同的64位

我不清楚你在问什么-如果你想要UTC值,为什么不现在在时区“UTC”使用呢?然后记录下它将始终是UTC,你没事吧?如果我从times中选择时区“UTC”的t;返回:-2017-06-13 10:53:17.766969-2017-06-13 14:53:17.766969我不确定存储层中发生了什么。但在UTC时插入和在UTC时选择似乎不一致。我怀疑,鉴于您所说的时区“UTC”时选择t的值实际上是说,假设表中的值是UTC,并将其转换为本地时间。这:在某种程度上同意,如果生成的带有时区的时间戳隐式转换为系统本地区域。。。我承认,SQL数据库总体上把这件事搞得一团糟。啊,是的,这就是行为。我了解了如何记录这一点:始终在时区“UTC”插入using NOW,并在不指定时区的情况下选择以检索UTC时间戳。
# select pg_typeof(now() at time zone 'utc');
timestamp without time zone

# select pg_typeof(now() at time zone 'utc' at time zone 'utc'); 
timestamp with time zone