2016-08-08 1 views
5

J'essaie de formater une représentation de date Postgres en une chaîne ISO 8601. Je suppose qu'il y a une fonction Postgres qui peut le faire, mais j'ai trouvé la documentation courte sur des exemples.Transformer la représentation de la date postgres en chaîne ISO 8601

Ma requête est

SELECT 
    now()::timestamp 

qui retourne

[{{2016, 8, 9}, {3, 56, 55, 754181}}] 

J'essaie d'obtenir la date dans un format qui ressemble plus à 2016-8-9T03:56:55+00:00.

Quels changements dois-je apporter à ma requête pour que cela se produise? Merci de votre aide.

+0

Lorsque vous postez sur Stack Overflow, conservez votre scénario et votre code d'exemple aussi courts et simples que possible. Votre requête complexe n'est pas pertinente pour la mise en forme d'une date-heure. Une seule ligne pour sélectionner le moment actuel est suffisante pour démontrer le problème. –

+0

@BasilBourque Je l'ai simplifié. – CallMeNorm

+0

Spécifiez l'info/tag sur le logiciel que vous utilisez pour vous connecter/interroger PostgreSQL. – Abelisto

Répondre

8

Je pense que j'ai trouvé un moyen de faire le formatage, mais ce n'est pas idéal car j'écris le formatage moi-même.

Voici une solution potentielle:

SELECT to_char (now()::timestamp at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') 
+0

ce formulaire ne fonctionne pas, au moins dans PG10. :: timestamp supprime timezoneinformation et 'at timezone UTC' décale à nouveau le décalage, donc vous le déplacez deux fois. (maintenant() au fuseau horaire 'UTC', 'AAAA-MM-JJ "T" HH24: MI: SS "Z"'); fonctionne dans le cas – smilee89

+0

Dans mon cas, j'ai aussi besoin des millisecondes, il suffit donc d'ajouter .MS après les secondes. 'To_char (now() :: horodatage au fuseau horaire 'UTC', 'AAAA-MM-JJ" T "HH24: MI: SS.MS" Z "')' – Brugolo

1

fonction ne fonctionnait pour moi parce que vous devez définir le fuseau horaire.

Pour avoir fuseau horaire de valeur par défaut avec la zone:

create table somedata (
    release_date timestamptz DEFAULT NOW() 
) 

Créer function:

CREATE OR REPLACE FUNCTION date_display_tz(param_dt timestamp with time zone) 
RETURNS text AS 
$$ 
DECLARE var_result varchar; 
BEGIN 
PERFORM set_config('timezone', 'UTC', true); 
var_result := to_char(param_dt , 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"'); 
RETURN var_result; 
END; 
$$ language plpgsql VOLATILE; 

Et sortie:

# SELECT 
# localtimestamp, current_timestamp, 
# to_char(localtimestamp, 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"'), 
# to_char(current_timestamp, 'YYYY-MM-DD"T"HH24:MI:SS:MS"Z"'), 
# date_display_tz(localtimestamp), date_display_tz(current_timestamp); 
     timestamp   |    now    |   to_char   |   to_char   |  date_display_tz  |  date_display_tz 
----------------------------+-------------------------------+--------------------------+--------------------------+--------------------------+-------------------------- 
2017-04-27 23:48:03.802764 | 2017-04-27 21:48:03.802764+00 | 2017-04-27T23:48:03:802Z | 2017-04-27T23:48:03:802Z | 2017-04-27T21:48:03:802Z | 2017-04-27T21:48:03:802Z 
(1 row) 

Regardez this aussi:

Si vous voulez que le serveur renvoie les informations de fuseau horaire respectives de un autre fuseau horaire, je crois que vous devrez utiliser SET TIME ZONE. Sinon, le serveur automatiquement (convertit l'horodatage) et renvoie le fuseau horaire du serveur.

test=# select (current_timestamp at time zone 'UTC') at time zone 'UTC'; 
      timezone 
------------------------------- 
    2005-04-22 16:26:57.209082+09 
(1 row) 

test=# set time zone 'UTC'; 
SET 
test=# select (current_timestamp at time zone 'UTC') at time zone 'UTC'; 
      timezone 
------------------------------- 
    2005-04-22 07:27:55.841596+00 
(1 row) 

test=# select (current_timestamp at time zone 'UTC'); 
      timezone 
---------------------------- 
    2005-04-22 07:28:48.888154 
(1 row) 

test=# select (current_timestamp at time zone 'UTC')::timestamptz; 
      timezone 
------------------------------- 
    2005-04-22 07:38:19.979511+00 
(1 row) 
+0

ou à l'aide de 'sql' lang insted of 'plpgsql'. 'select ret de (select set_config ('timezone', tzone, true), to_char (tstamp, masque) ret) t;' https://pastebin.com/EC9KPfZ7 –

3

Peut-être que pour quelqu'un, il serait utile de savoir que depuis la fonction Postgres 9.4 to_json (ainsi que row_to_json) convertit également horodatage à un bon format ISO 8601 mais En outre, il ajoute une valeur entre guillemets qui pourrait ne pas être souhaitable:

SELECT now(); 
    2017-05-10 15:57:23.736054+03 

SELECT to_json(now()); 
    "2017-05-10T15:57:23.769561+03:00" 

-- in case you want to trim the quotes 
SELECT trim(both '"' from to_json(now())::text); 
    2017-05-10T15:57:23.806563+03:00 
+1

'to_json (now())' n'a pas le 'T' dedans dans Postgres 9.3 – cdmckay

+0

@cdmckay, merci de m'avoir fait remarquer, j'ai ajouté à la réponse:" depuis 9.6 "bien que je n'ai pas essayé d'exécuter la requête en 9.5 et 9.4. – Dattaya

+0

c'est bien dans 9.4 et 9.5, seulement 9.3 a le T étrangeté – cdmckay

1

Définir la variable de session timezone à tout ce fuseau horaire que vous voulez que la sortie soit dans, puis utilisez to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF')

Si vous utilisez at time zone '...' savoir que cela dépouiller toute information de fuseau horaire, et supposons que l'utilisateur connaît déjà le fuseau horaire.

Si vous utilisez at time zone 'UTC', la sortie doit toujours être l'heure UTC, avec les informations de fuseau horaire correctes (pas de décalage).

set timezone='UTC'; 


select to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF'); 

2017-11-17T02:02:26+00 /* UTC time */ 


select to_char(now() at time zone 'Australia/Sydney', 'YYYY-MM-DD"T"HH24:MI:SSOF'); 

2017-11-17T13:02:26+00 /* Local Sydney time, but note timezone is incorrect. */ 


set timezone='Australia/Sydney'; 


select to_char(now(), 'YYYY-MM-DD"T"HH24:MI:SSOF'); 

2017-11-17T13:02:26+11 /* Local Sydney time with correct time zone! */ 


select to_char(now() at time zone 'Australia/Sydney', 'YYYY-MM-DD"T"HH24:MI:SSOF'); 

2017-11-17T13:02:26+00 /* Still local Sydney time, but time zone info has been removed. */ 


select to_char(now() at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SSOF'); 

2017-11-17T02:02:26+00 /* Correct UTC time with correct offset. */ 

This blog post donne une explication assez détaillée.