Il existe une réponse longue et assez élucidante sur les différences entre
TIMESTAMP WITH TIME ZONE
-contre-TIMESTAMP WITHOUT TIME ZONE
disponible dans cet article SO . Ce que je voudrais savoir, c’est: existe-t-il des cas d’utilisation valables pour une utilisation effective TIMESTAMP WITHOUT TIME ZONE
ou faut-il en faire un anti-pattern?
postgresql
Marcus Junius Brutus
la source
la source
Réponses:
Ceci est indiqué dans de nombreux endroits, mais je pense qu'il est toujours utile de mentionner quand on compare les types
timestamp with time zone
avectimestamp without time zone
: letimestamp WITH time zone
ne stocke pas les informations de fuseau horaire avec l'horodatage . Ce que cela fait est de stocker toutes les données dans le fuseau horaire UTC, comme indiqué dans la documentation :Il est considéré comme valide pour certains à utiliser
timestamp WITHOUT time zone
dans des situations où (1) tout se trouve dans le même fuseau horaire ou (2) que la couche d’application gère le fuseau horaire et ne stocke que tout dans un certain fuseau horaire (généralement UTC). Mais cela est également considéré comme un anti-motif, simple car la solution correcte pour (1) consiste à configurer le paramètre TimeZone sur le fuseau horaire donné pour le système et (2) est déjà résolu, car PostgreSQL enregistre déjà tout sur le même fuseau horaire. (UTC).Maintenant, avec ces deux bas, je peux venir avec une seule bonne raison d'utiliser
timestamp WITHOUT time zone
. C'est à ce moment-là que vous souhaitez stocker des événements dans le futur et qu'une sorte d'alerte doit être déclenchée lorsque nous sommes arrivés à cette heure. Cela pourrait être utiletimestamp WITH time zone
si et seulement si les règles définies par les lois de la région concernant le fuseau horaire ne changeaient jamais. La règle la plus courante qui change concerne l’adoption ou non de l’heure avancée.Par exemple, imaginons que vous êtes en train (par exemple,
2013-06-15
pas encore à l'heure d'été) de programmer un événement à2013-01-15 10:00
(qui serait déjà en heure d'été), et que2013-06-15
votre région a été désignée pour adopter l'heure d'été; mais quelque temps après cela, le gouvernement a changé la règle et a déclaré que votre région n'utilisera plus l'heure d'été, et que l'heure programmée devient2013-01-15 11:00
(au lieu de10:00
) celle que vous utiliserez si vous utiliseztimestamp WITH time zone
et maintenez vos configurations TZ à jour. Bien sûr, vous remarquerez peut-être qu'il est également possible de traiter de tels cas avec le fuseau horaire, si vous suivez les changements de règles dans les régions / fuseaux horaires qui vous intéressent et mettez à jour les enregistrements concernés.Il est à noter que certaines régions modifient souvent ces règles (comme au Brésil, certains États - mais pas tout le pays - changent souvent), mais dans la plupart des cas, cela change très tôt, afin que vos utilisateurs ne soient affectés que par des événements très éloignés. l'heure actuelle.
Cela dit, je n’ai qu’une suggestion de plus. Si vous avez des utilisateurs, des journaux ou quoi que ce soit sur des fuseaux horaires différents, stockez le fuseau horaire d'où ils viennent et choisissez et utilisez-le
timestamp with time zone
. De cette façon, vous pouvez (1) traverser des événements se produisant plus proches les uns des autres pour différentes sources (indépendamment de leur fuseau horaire) et (2) afficher l'heure d'origine (l'heure de l'horloge) à laquelle l'événement s'est produit.la source
Oui. Il existe des cas d'utilisation pour
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
, pasWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
les valeurs ne sont pas un point sur la timeline, pas des moments réels. Ils représentent une idée approximative des moments potentiels , des points possibles sur la timeline sur une plage d’environ 26 à 27 heures (la plage des fuseaux horaires dans le monde). Ils n'ont aucune signification réelle jusqu'à ce que vous appliquiez un fuseau horaire ou un décalage par rapport à UTC .Ex: Noël
Par exemple, supposons que vous deviez enregistrer le début des vacances / jours saints.
Pour enregistrer le fait que Noël commence après minuit le 25 décembre de cette année, nous devons dire
2016-12-25 00:00:00
sans fuseau horaire. Au début de la journée du père Noël, il se rend à Auckland en Nouvelle-Zélande juste après minuit, car il s'agit de l'un des tout premiers mid-night du monde. Ensuite, il se dirige vers l’Ouest, comme à l’heure suivante, pour atteindre bientôt les Philippines. Ensuite, les rennes se dirigent vers l’ouest pour atteindre l’Inde à minuit, plusieurs heures après celle d’Auckland. Beaucoup plus tard, il est toujours minuit à Paris FR et encore plus tard minuit à Montréal, en Californie. Toutes ces visites du père Noël ont lieu à des moments différents , mais toutes se sont déroulées peu de temps après minuit, par minuit propre à chaque localité.Donc, enregistrer
2016-12-25 00:00:00
sans le fuseau horaire que le début de Noël est informatif et légitime, mais seulement vaguement. Jusqu'à ce que vous disiez «Noël à Auckland» ou «Noël à Montréal», nous n'avons pas de moment précis dans le temps. Si vous enregistrez le moment réel à chaque fois que le traîneau touche le sol, vous utiliserezTIMESTAMP WITH TIME ZONE
plutôt que leWITHOUT
type.Semblable à Noël, c'est le réveillon du nouvel an. Lorsque le Times Square Ball tombe à New York , les habitants de Seattle gardent toujours leur champagne au froid et préparent leurs cornes de fête . Pourtant, nous enregistrons l' idée du moment du Nouvel An comme
2017-01-01 00:00:00
dans unTIMESTAMP WITHOUT TIME ZONE
. En revanche, si nous voulons enregistrer quand le ballon est tombé à New York ou quand les habitants de Seattle s’essoufflent, nous utiliseronsTIMESTAMP WITH TIME ZONE
(nonWITHOUT
) pour enregistrer ces moments réels, à trois heures d’écart l'un de l'autre.Ex: déplacements d'usine
Un autre exemple pourrait consister à enregistrer une politique qui implique une heure fixe sur différents emplacements. Supposons que nous ayons des usines à Détroit, Düsseldorf et Delhi. Si nous disons que dans les trois usines, le premier quart de travail commence à 6 heures du matin et la pause du déjeuner à 11h30, cela pourrait être enregistré comme
TIMESTAMP WITHOUT TIME ZONE
. Encore une fois, cette information est utile de manière vague mais n'indique pas un moment précis avant l'application d'un fuseau horaire. Un nouveau jour se lève plus tôt dans l'est. L’usine de Delhi sera donc la première à ouvrir à 6 heures du matin. Quelques heures plus tard, l’usine de Düsseldorf commence à travailler à 6 heures du matin. Mais l’usine de Detroit n’ouvrira réellement que six heures plus tard, au plus tard à 6 heures.Comparez cette idée (du début de l'équipe d'usine en général) au fait historique de savoir quand chaque ouvrier d'usine a commencé à effectuer son service un jour donné. Le chronométrage est un moment réel, un point réel sur la timeline. Nous enregistrons donc cela dans une colonne de type
TIMESTAMP WITH TIME ZONE
plutôt que deWITHOUT
type.Donc, oui, il existe des cas d'utilisation légitimes pour
TIMESTAMP WITHOUT TIME ZONE
. Mais d'après mon expérience avec les applications professionnelles, elles sont relativement rares. En affaires, nous avons tendance à nous soucier des moments réels: quand la facture est-elle réellement arrivée, quand exactement ce contrat a-t-il pris effet, à quel moment cette transaction bancaire a-t-elle été exécutée? Donc, dans de telles situations courantes, nous voulons leTIMESTAMP WITH TIME ZONE
type.Pour plus de discussion, voir ma réponse à la question similaire, devrais-je stocker des horodatages UTC ou des heures locales pour les équipes
Postgres
Notez que Postgres n'enregistre jamais spécifiquement les informations de fuseau horaire spécifiées lors de l'insertion d'un horodatage.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
àTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
Le standard SQL aborde à peine les problèmes de comportement et de types de données date-heure. La base de données varie donc beaucoup dans le traitement de la date et de l’heure.
la source
21:00
J'aimerais ajouter un autre point de vue à cela, qui va à l'encontre d'une grande partie de ce qui a été écrit dans les autres réponses. À mon avis,
timestamp with time zone
a très peu de cas d'utilisation valables, ettimestamp without time zone
devrait généralement être préféré.Tout d’abord, vous devez comprendre le modèle "UTC partout", qui est généralement recommandé pour toutes les applications qui n’exigent pas d’exigences particulières. Cela signifie simplement que votre application doit représenter tous ses horodatages en UTC, partout et tout le temps. Bien sûr, vous allez montrer la date / heure locale aux utilisateurs, mais l’idée est de les convertir au bord de votre programme, lors du rendu de la vue. C’est le bon endroit pour combiner l’horodatage UTC (que vous avez peut-être chargé depuis une base de données) et le fuseau horaire de l’utilisateur (qui peut provenir du navigateur) dans un horodatage local.
Si vous suivez ce modèle, alors
timestamp with time zone
est un anti-modèle. Tout ce type fait que PostgreSQL ™ effectue des conversions de fuseau horaire lors de la lecture et de l'écriture d'horodatages, en fonction de votreTimeZone
variable de session PostgreSQL . Au lieu de traiter les fuseaux horaires aux limites de votre application, vous les avez introduits dans son cœur, dans la communication même avec votre base de données. Vous devez veiller à toujours avoirTimeZone
correctement configuré PostgreSQL à tout moment, en ajoutant un autre point de défaillance et de confusion inutile.Et pour quoi? Si vous suivez le modèle UTC partout, votre application n’a de toute façon que des horodatages UTC; alors pourquoi demander à votre base de données d’effectuer des conversions de fuseaux horaires sur celles-ci? Vous pouvez simplement les stocker dans une
timestamp without time zone
colonne et les traiter comme si c'était toujours UTC. Pas de conversions, pas de fuseaux horaires, pas de complications.la source
Instance
dans NodaTime / JodaTime). Vous décrivez en gros une situation dans laquelle "UTC partout" est presque suivie, ou un peu suivie ...timestamptz
. L’intérêt de ce type est d’effectuer des conversions de fuseau horaire en tant que valeurs lues et écrites dans PostgreSQL (en interne dans la base de données, l’horodatage est toujours enregistré au format UTC). Le fait de toujours définir le fuseau horaire de la session sur UTC désactive efficacement ces conversions, alors pourquoi l'utilisertimestamptz
? En d'autres termes, si les valeurs de la base de données sont UTC et que les valeurs entrant et sortant de la base de données sont toujours UTC, pourquoi avoir la présence d'un fuseau horaire dans votre base de données?L’
date
horodatage n’inclut pas non plus les informations de fuseau horaire, mais beaucoup de gens l’utilisent.Bien sûr, cela en soi n'est pas une réponse.
Il est valide d'utiliser
timestamp
etdate
pour tous les horodatages et dates qui sont toujours dans le même fuseau horaire ou qui sont stockés par rapport à un fuseau horaire connu.Si le fuseau horaire est toujours identique ou implicite, il est plus contraignant de le stocker que de ne pas le stocker (informations redondantes).
Les horodatages peuvent également être utilisés pour stocker des informations techniques telles que celles utilisées dans les journaux d'application ou pour les mesures de performances. Dans ce cas, le fuseau horaire peut également être sans importance.
Inversement, si vous concevez ou travaillez sur un système distribué ou dans un système dans lequel des parties du système seront réparties sur des fuseaux horaires différents, cela peut être considéré comme un anti-motif à ne pas utiliser
timestamp with timezone
, même si certains systèmes peuvent être conçus pour s'exécuter dans un fuseau horaire, p.ex. UTC. Dans ce cas, la logique du fuseau horaire peut être poussée dans la couche application - mais je considérerais cela comme un anti-motif, oui.la source
timestamp without timezone
, mais est-ce que cela m’achète quelque chose? Sinon, pourquoi devrais-je m'embêter si letimestamp with timezone data
type est toujours égal ou plus approprié?timestamp without timezone
serait plus rapide aussi, mais ce n'est probablement important que si vous traitez des milliards de lignes ...timestamp
ettimestamptz
sont tous deux stockés de la même manière. Aucune information de fuseau horaire n'est stockée dans atimestamptz
, mais elle est convertie au format UTC pour le stockage. Je dirais, utilisez toujourstimestamptz
lorsque les horodatages en question indiquent l'heure absolue . C'est tout ce quetimestamptz
signifie. J'ai écrit à ce sujet ici .Il peut sembler temporaire de stocker et de traiter les dates / heures à l’heure locale si votre application est limitée à un seul fuseau horaire, mais j’estime qu’il s’agit d’une erreur.
Lorsque vous passez de l'heure d'été à l'heure normale, l'heure locale est répétée (en supposant que la différence est d'une heure). Là où j'habite, cela se produit généralement autour de 2 heures du matin, donc l'heure locale est 01:58, 01:59, 01:00 et ne avance qu'à 02:00 à la fin de l'heure.
Si vous essayez de classer les événements par heure en utilisant l'heure locale, cela signifie que les événements de deux heures distinctes sont mélangés et n'apparaissent pas dans l'ordre dans lequel ils se sont réellement déroulés.
En comparaison, UTC n'a pas ce problème et commande proprement. Ainsi, même lorsque vous travaillez avec un seul fuseau horaire, vous souhaitez que la base de données stocke et traite les heures au format UTC et les convertisse en / à partir de l'heure locale à des fins de saisie / affichage. C'est le comportement de TIMESTAMP WITH TIME ZONE.
la source