Использование текущего времени в UTC в качестве значения по умолчанию в PostgreSQL

У меня есть колонка 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...

6 ответов

Решение

Функция даже не нужна. Просто поместите скобки вокруг выражения по умолчанию:

create temporary table test(
    id int, 
    ts timestamp without time zone default (now() at time zone 'utc')
);

Еще одно решение:

timezone('utc', now())

Оберните это в функцию:

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()
);

Как насчет

now()::timestamp

Если ваша другая временная метка без часового пояса, тогда это приведение даст соответствующий тип "временная метка без часового пояса" для текущего времени.

Я хотел бы прочитать, что другие думают об этом варианте, хотя. Я все еще не верю в мое понимание этого "с / без" материала о часовом поясе.

Это 2 эквивалентных решения:

(использование 'UTC' для зоны и now() для отметки времени)

  1. timestamp AT TIME ZONE zone - Соответствие стандарту SQL
  2. timezone(zone, timestamp) - возможно, более читаемый

Функция timezone (zone, timestamp) эквивалентна временной метке, соответствующей конструкции SQL, в зоне AT TIME ZONE.


Объяснение:

  • зона может быть указана в виде текстовой строки (например, 'UTC') или в качестве интервала (например, INTERVAL '-08:00') - вот список всех доступных часовых поясов
  • отметка времени может быть любым значением типа отметка времени
  • now() возвращает значение типа timestamp (именно то, что нам нужно) с привязанным часовым поясом по умолчанию вашей базы данных (например, 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,

Документы: часовой пояс ()

Функция уже существует: часовой пояс ('UTC'::text, now())

Другие вопросы по тегам