web-dev-qa-db-fra.com

Utiliser l'heure actuelle dans UTC comme valeur par défaut dans PostgreSQL

J'ai une colonne du type TIMESTAMP WITHOUT TIME ZONE et je voudrais que cette valeur par défaut corresponde à l'heure actuelle en UTC. Obtenir l'heure actuelle en UTC est facile:

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

En utilisant l'horodatage actuel d'une colonne:

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)

Mais cela utilise l'heure locale. Essayer de forcer cela à UTC entraîne une erreur de syntaxe:

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...
116
Wichert Akkerman

Une fonction n'est même pas nécessaire. Il suffit de mettre des parenthèses autour de l'expression par défaut:

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

Enveloppez-le dans une fonction:

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

Encore une autre solution: 

timezone('utc', now())
20
martti

Qu'en est-il de

now()::timestamp

Si votre autre horodatage est sans fuseau horaire, cette conversion donnera le type correspondant "horodatage sans fuseau horaire" pour l'heure actuelle.

J'aimerais toutefois lire ce que les autres pensent de cette option. Je ne fais toujours pas confiance à ma compréhension de cette zone "avec/sans" fuseau horaire.

14
Risadinha

La fonction existe déjà: Timezone ('UTC' :: text, now ())

1
user10259440

Ce sont 2 solutions équivalentes:

(utilisez 'UTC' pour zone et now() pour horodatage)

  1. timestamp AT TIME ZONE zone - conforme à la norme SQL
  2. timezone(zone, timestamp) - sans doute plus lisible

La fonction timezone (zone, timestamp) est équivalente à la zone timestamp de construction conforme à SQL AT TIME ZONE.


Explication:

  • zone peut être spécifié en tant que chaîne de texte (par exemple, 'UTC') ou en tant qu'intervalle (par exemple, INTERVAL '-08:00') - voici une liste de tous les fuseaux horaires disponibles
  • timestamp peut être n'importe quelle valeur de type timestamp _
  • now() renvoie une valeur de type timestamp (exactement ce dont nous avons besoin) avec le fuseau horaire par défaut de votre base de données (par exemple, 2018-11-11T12:07:22.3+05:00).
  • timezone('UTC', now()) transforme notre heure actuelle (de type horodatage avec fuseau horaire) en équivalent timezonless dans UTC.
    E.g., SELECT timestamp with time zone '2020-03-16 15:00:00-05' AT TIME ZONE 'UTC' retournera 2020-03-16T20:00:00Z.

Docs: timezone ()

0
lakesare