225

我有一个类型的列,TIMESTAMP WITHOUT TIME ZONE并希望将其默认设置为 UTC 中的当前时间。以 UTC 格式获取当前时间很容易:

postgres=# select now() at time zone 'utc';
          timezone          
----------------------------
 2013-05-17 12:52:51.337466
(1 row)

与使用列的当前时间戳一样:

postgres=# create temporary table test(id int, ts timestamp without time zone default current_timestamp);
CREATE TABLE
postgres=# insert into test values (1) returning ts;
             ts             
----------------------------
 2013-05-17 14:54:33.072725
(1 row)

但这使用的是当地时间。试图将其强制为 UTC 会导致语法错误:

postgres=# create temporary table test(id int, ts timestamp without time zone default now() at time zone 'utc');
ERROR:  syntax error at or near "at"
LINE 1: ...int, ts timestamp without time zone default now() at time zo...
4

6 回答 6

375

甚至不需要函数。只需在默认表达式周围加上括号:

create temporary table test(
    id int, 
    ts timestamp without time zone default (now() at time zone 'utc')
);
于 2013-05-17T13:30:51.697 回答
94

还有一个解决方案:

timezone('utc', now())
于 2018-01-05T19:46:29.097 回答
35

将其包装在一个函数中:

create function now_utc() returns timestamp as $$
  select now() at time zone 'utc';
$$ language sql;

create temporary table test(
  id int,
  ts timestamp without time zone default now_utc()
);
于 2013-05-17T13:04:15.600 回答
19

关于什么

now()::timestamp

如果您的其他时间戳没有时区,那么此转换将产生当前时间的匹配类型“没有时区的时间戳”。

不过,我想了解其他人对该选项的看法。我仍然不相信我对这个“有/没有”时区的理解。

编辑:在此处添加 Michael Ekoka 的评论,因为它阐明了一个重要点:

警告。问题是关于在 UTC 中为恰好不存储时区的时间戳列生成默认时间戳(可能是因为如果您知道所有时间戳共享相同,则无需存储时区)。您的解决方案所做的是生成一个本地时间戳(对于大多数人来说,不一定将其设置为 UTC)并将其存储为一个简单的时间戳(一个未指定其时区的时间戳)。

于 2014-07-16T15:23:11.877 回答
10

这些是 2 个等效的解决方案:

(在下面的代码中,您应该'UTC'替换zonetimestampnow()

  1. timestamp AT TIME ZONE zone- 符合 SQL 标准的
  2. timezone(zone, timestamp)- 可以说更具可读性

函数 timezone(zone, timestamp) 等价于符合 SQL 的构造 timestamp AT TIME ZONE zone。


解释:

  • zone可以指定为文本字符串(例如,'UTC')或间隔(例如,INTERVAL '-08:00') - 这是所有可用时区的列表
  • 时间戳可以是时间戳类型的任何值
  • now()返回一个时间戳类型的值(正是我们需要的),并附有数据库的默认时区(例如2018-11-11T12:07:22.3+05:00)。
  • timezone('UTC', now())将我们当前的时间(类型为带时区的时间戳)转换为UTC.
    例如,SELECT timestamp with time zone '2020-03-16 15:00:00-05' AT TIME ZONE 'UTC'将返回2020-03-16T20:00:00Z

文档:时区()

于 2018-11-11T07:40:29.057 回答
3

函数已经存在:timezone('UTC'::text, now())

于 2018-08-22T11:26:42.107 回答