IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

8.5. Types date/heure

PostgreSQL™ supporte l'ensemble des types date et heure du SQL. Ces types sont présentés dans le Tableau 8.9, « Types date et heure ». Les opérations disponibles sur ces types de données sont décrites dans la Section 9.9, « Fonctions et opérateurs sur date/heure ».


[Note]

Note

Précédemment à PostgreSQL™ 7.3, n'écrire que timestamp équivalait à timestamp with time zone. Cela a été modifié pour des raisons de compatibilité avec le standard SQL.

time, timestamp, et interval acceptent une précision optionnelle p , qui indique le nombre de décimales pour les secondes. Il n'y a pas, par défaut, de limite explicite à cette précision. Les valeurs acceptées pour p s'étendent de 0 à 6 pour les types timestamp et interval.

[Note]

Note

Quand les valeurs timestamp sont stockées en tant que nombre à virgule flottante de précision double (par défaut à l'heure actuelle), la limite réelle de la précision peut être inférieure à 6. Les valeurs timestamp sont stockées comme un nombre de secondes avant ou après le 1er janvier 2000 à minuit. La précision à la microseconde est obtenue pour les dates proches du 1er janvier 2000, mais elle se dégrade pour les dates plus éloignées. Quand les valeurs timestamp sont stockées sur des entiers de huit octets (une option de compilation), la précision en microseconde est disponible sur toute l'étendue de valeurs. Néanmoins, les valeurs de type timestamp codées sur des entiers de huit octets ont une échelle de date plus restreinte que celle indiquée ci-dessus : de 4713 avant Jésus-Christ à 294276 après Jésus-Christ. La même option de compilation détermine si les valeurs time et interval sont stockées comme nombres à virgule flottante ou comme entiers sur huit octets. Dans le cas de la virgule flottante, la précision des grandes valeurs interval se dégradent à mesure que l'intervalle croît.

Pour les types time, l'intervalle accepté pour p s'étend de 0 à 6 pour les entiers sur 8 octets et de 0 à 10 pour les nombres à virgule flottante.

Le type time with time zone est défini dans le standard SQL mais sa définition lui prête des propriétés qui font douter de son utilité. Dans la plupart des cas, une combinaison de date, time, timestamp without time zone et timestamp with time zone devrait permettre de résoudre toutes les fonctionnalités de date et heure nécessaires à une application.

Les types abstime et reltime sont des types de précision moindre, utilisés en interne. Il n'est pas recommandé de les utiliser dans de nouvelles applications. Au contraire, il est souhaitable de migrer l'existant vers un autre type approprié. Il est probable que l'un ou l'autre (voire tous) de ces types internes disparaisse(nt) dans une future version.

La saisie de dates et heures peut se faire dans la plupart des formats raisonnables, dont ISO8601, tout format compatible avec SQL, le format POSTGRES™ traditionnel ou autres. Pour certains formats, l'ordre des jours, mois et années en entrée est ambigu. Il est alors possible de préciser l'ordre attendu pour ces champs. Le paramètre datestyle peut être positionné à MDY pour choisir une interprétation mois-jour-année, à DMY pour jour-mois-année ou à YMD pour année-mois-jour.

PostgreSQL™ est plus flexible que la norme SQL ne l'exige pour la manipulation des dates et des heures. Voir l'Annexe B, Support de date/heure pour connaître les règles exactes de reconnaissance des dates et heures et les formats reconnus pour les champs texte comme les mois, les jours de la semaine et les fuseaux horaires.

Tout libellé de date ou heure saisi doit être placé entre apostrophes, comme les chaînes de caractères. La Section 4.1.2.5, « Constantes d'autres types » peut être consultée pour plus d'information. SQL requiert la syntaxe suivante :

type [ (p) ] 'valeur'

p , précision optionnelle, est un entier correspondant au nombre de décimales du champ secondes. La précision peut être précisée pour les types time, timestamp, et interval. Les valeurs admissibles sont mentionnées plus haut. Si aucune précision n'est indiquée dans une déclaration de constante, celle de la valeur littérale est utilisée.

Les types heure-du-jour sont time [ ( p ) ] without time zone et time [ ( p ) ] with time zone. time est équivalent à time without time zone.

Les saisies valides pour ces types sont constituées d'une heure suivie éventuellement d'un fuseau horaire (voir le Tableau 8.11, « Saisie d'heure » et le Tableau 8.12, « Saisie des fuseaux horaires »). Si un fuseau est précisé pour le type time without time zone, il est ignoré sans message d'erreur. Si une date est indiquée, elle est ignorée sauf si un fuseau horaire impliquant une règle de changement d'heure (heure d'été/heure d'hiver) est précisé, America/New_York par exemple. Dans ce cas, la date est nécessaire pour pouvoir déterminer la règle de calcul de l'heure qui s'applique. Le décalage approprié du fuseau horaire est enregistré dans la valeur de time with time zone.



L'Section 8.5.3, « Fuseaux horaires » apporte des précisions quant à la façon d'indiquer les fuseaux horaires.

Les saisies valides sont constituées de la concaténation d'une date et d'une heure, éventuellement suivie d'un fuseau horaire et d'un qualificatif AD (après Jésus Christ) ou BC (avant Jésus Christ). (AD/BC peut aussi apparaître avant le fuseau horaire mais ce n'est pas l'ordre préféré.) Ainsi :

1999-01-08 04:05:06

et

1999-01-08 04:05:06 -8:00

sont des valeurs valides, qui suivent le standard ISO 8601. Le format très courant

January 8 04:05:06 1999 PST

est également supporté.

Le standard SQL différencie les libéllés timestamp without time zone et timestamp with time zone par la présence d'un « + » ou d'un « - ». De ce fait, d'après le standard,

TIMESTAMP '2004-10-19 10:23:54'

est du type timestamp without time zone alors que

TIMESTAMP '2004-10-19 10:23:54+02'

est du type timestamp with time zone. PostgreSQL™ n'examine jamais le contenu d'un libellé avant de déterminer son type. Du coup, il traite les deux ci-dessus comme des valeurs de type timestamp without time zone. Pour s'assurer qu'un littéral est traité comme une valeur de type timestamp with time zone, il faut préciser explicitement le bon type :

TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'

Dans un libellé de type timestamp without time zone, PostgreSQL™ ignore silencieusement toute indication de fuseau horaire. C'est-à-dire que la valeur résultante est dérivée des champs date/heure de la valeur saisie et n'est pas corrigée par le fuseau horaire.

Pour timestamp with time zone, la valeur stockée en interne est toujours en UTC ( Universal Coordinated Time ou Temps Universel Coordonné), aussi connu sous le nom de GMT ( Greenwich Mean Time ). Les valeurs saisies avec un fuseau horaire explicite sont converties en UTC à l'aide du décalage approprié. Si aucun fuseau horaire n'est précisé, alors le système considère que la date est dans le fuseau horaire indiqué par le paramètre système timezone, et la convertit en UTC en utilisant le décalage de la zone timezone.

Quand une valeur timestamp with time zone est affichée, elle est toujours convertie de l'UTC vers le fuseau horaire courant (variable timezone), et affichée comme une heure locale. Pour voir l'heure dans un autre fuseau horaire, il faut, soit changer la valeur de timezone, soit utiliser la construction AT TIME ZONE (voir la Section 9.9.3, « AT TIME ZONE »).

Les conversions entre timestamp without time zone et timestamp with time zone considèrent normalement que la valeur timestamp without time zone utilise le fuseau horaire timezone. Un fuseau différent peut être choisi en utilisant AT TIME ZONE.

PostgreSQL™ supporte plusieurs valeurs de dates spéciales, dans un souci de simplification. Ces valeurs sont présentées dans le Tableau 8.13, « Saisie de dates/heures spéciales ». Les valeurs infinity et -infinity ont une représentation spéciale dans le système et sont affichées ainsi ; les autres ne sont que des raccourcies de notation convertis en dates/heures ordinaires lorsqu'ils sont lus. (En particulier, now et les chaînes relatives sont converties en une valeur de temps spécifique à leur lecture). Toutes ces valeurs doivent être écrites entre simples quotes lorsqu'elles sont utilisées comme des constantes dans les commandes SQL.


Les fonctions suivantes, compatibles avec le standard SQL, peuvent aussi être utilisées pour obtenir l'heure courante pour le type de données correspondant : CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, LOCALTIME, LOCALTIMESTAMP. Les quatre derniers acceptent une indication optionnelle de précision en dessous de la seconde (voir la Section 9.9.4, « Date/Heure courante »). Ce sont là des fonctions SQL qui ne sont pas reconnues comme chaînes de saisie de données.

Le format de sortie des types date/heure peut être positionné à l'un des quatre formats de date suivants : ISO 8601, SQL (Ingres), traditionnel POSTGRES et German (germanique). Cela se fait à l'aide de la commande SET datestyle. Le format par défaut est le format ISO. (Le standard SQL impose l'utilisation du format ISO 8601. Le nom du format d'affichage « SQL » est un accident historique.) Le Tableau 8.14, « Styles d'affichage de date/heure » présente des exemples de chaque format d'affichage. La sortie d'un type date ou time n'est évidemment composée que de la partie date ou heure, comme montré dans les exemples.


Dans les styles SQL et POSTGRES, les jours apparaissent avant le mois si l'ordre des champs DMY a été précisé, sinon les mois apparaissent avant les jours (voir la Section 8.5.1, « Saisie des dates et heures » pour savoir comment ce paramètre affecte l'interprétation des valeurs en entrée). Le Tableau 8.15, « Convention de présentation des dates » présente un exemple.


L'affichage du type interval ressemble au format de saisie, à ceci près que les unités comme century ou week sont converties en années et jours, et que ago est converti en un signe approprié. En mode ISO, l'affichage ressemble à :

[ quantité unité [ ... ] ] [ jours ] [ heures:minutes:secondes ]

Les styles de date/heure peuvent être sélectionnés à l'aide de la commande SET datestyle , du paramètre datestyle du fichier de configuration postgresql.conf ou par la variable d'environnement PGDATESTYLE sur le serveur ou le client. La fonction de formatage to_char (voir Section 9.8, « Fonctions de formatage des types de données ») permet de formater les affichages de date/heure de manière plus flexible.

Les fuseaux horaires et les conventions liées sont influencées par des décisions politiques, pas uniquement par la géométrie de la terre. Les fuseaux horaires se sont quelque peu standardisés au cours du vingtième siècle mais continuent à être soumis à des changements arbitraires, particulièrement en respect des règles de changement d'heure (heure d'été/heure d'hiver). PostgreSQL™ gère actuellement les règles de changement d'heure pour la période de 1902 à 2038 (qui correspond à l'intégralité de l'échelle du temps système Unix). Les heures en dehors de cette échelle sont prises dans le « temps standard » du fuseau horaire sélectionné, quelque soit la partie de l'année où elles tombent.

PostgreSQL™ se veut compatible avec les définitions standard SQL pour un usage typique. Néanmoins, le standard SQL possède un mélange étrange de types de date/heure et de possibilités. Deux problèmes évidents sont :

  • bien que le type date n'ait pas de fuseau horaire associé, le type heure peut en avoir un. Les fuseaux horaires, dans le monde réel, ne peuvent avoir de sens qu'associés à une date et à une heure, vu que l'écart peut varier avec l'heure d'été ;

  • le fuseau horaire par défaut est précisé comme un écart numérique constant avec l'UTC. Il n'est, de ce fait, pas possible de s'adapter à l'heure d'été ou d'hiver lorsque l'on fait des calculs arithmétiques qui passent les limites de l'heure d'été et de l'heure d'hiver.

Pour éviter ces difficultés, il est recommandé d'utiliser des types date/heure qui contiennent à la fois une date et une heure lorsque les fuseaux horaires sont utilisés. Il est également préférable de ne pas utiliser le type time with time zone. (Ce type est néanmoins proposé par PostgreSQL™ pour les applications existantes et pour assurer la compatibilité avec le standard SQL.) PostgreSQL™ utilise le fuseau horaire local pour tous les types qui ne contiennent qu'une date ou une heure.

Toutes les dates et heures liées à un fuseau horaire sont stockées en interne en UTC. Elles sont converties en heure locale dans le fuseau indiqué par le paramètre de configuration timezone avant d'être affiché sur le client.

PostgreSQL™ permet d'indiquer les fuseaux horaires de trois façons différentes :

  • un nom complet de fuseau horaire, par exemple America/New_York. Les noms reconnus de fuseau horaire sont listés dans la vue pg_timezone_names (voir Section 43.49, « pg_timezone_names »). PostgreSQL™ utilise les données zic pour cela, les mêmes noms sont donc reconnus par de nombreux autres logiciels ;

  • une abréviation de fuseau horaire, par exemple PST. Une telle indication ne définit qu'un décalage particulier à partir d'UTC, en contraste avec les noms complets de fuseau horaire qui peuvent aussi impliquer un ensemble de dates pour le changement d'heure. Les abréviations reconnues sont listées dans la vue pg_timezone_abbrevs (voir Section 43.48, « pg_timezone_abbrevs »). Le paramètre de configuration timezone ne peut pas être configuré à l'aide d'une abréviation de fuseau horaire, mais ces abréviations peuvent être utilisées dnas les saisies de date/heure et avec l'opérateur AT TIME ZONE ;

  • une spécification POSIX de fuseau sous la forme STD décalage ou STD décalage DST avec STD une abréviation de fuseau et décalage un décalage numérique en nombre d'heures à l'ouest d'UTC et DST une abréviation optionnelle de changement d'heure, à interpréter comme une heure avant le décalage donné. Par exemple si EST5EDT n'est pas déjà reconnu comme fuseau horaire, il est accepté et est fonctionnellement équivalent à l'heure du fuseau de la côte est des USA. Si un nom de changement d'heure est présent, il est interprété selon les règles régissant les changements d'heure utilisées dans l'entrée posixrules de la base de données des fuseaux horaires, zic. Dans une installation PostgreSQL™ standard, posixrules est identique à US/Eastern, pour que les spécifications POSIX des fuseaux horaires correspondent aux règles de changements d'heure aux États-Unis. Ce comportement peut, au besoin, être ajusté en remplaçant le fichier posixrules.

Il y a une différence conceptuelle et pratique entre les abréviations et les noms complets : les abréviations représentent toujours un décalage fixe par rapport à UTC alors que la plupart des noms complets impliquent une règle de changement d'heure et donc deux décalages possibles.

La fonctionnalité des fuseaux horaires POSIX peut accepter silencieusement des saisies erronées car il n'y a pas de vérification des abréviations de fuseaux horaires. Par exemple, SET TIMEZONE TO FOOBAR0 fonctionne mais conduit le système à utiliser en réalité une abréviation très particulière d'UTC.

Dans tous les cas, les noms des fuseaux horaires sont insensibles à la casse. (C'est un changement par rapport aux versions de PostgreSQL™ antérieures à la 8.2 qui étaient sensibles à la casse dans certains cas et pas dans d'autres.)

Ni les noms complets ni les abréviations ne sont codés en dur dans le serveur ; ils sont obtenus à partir des fichiers de configuration stockés sous .../share/timezone/ et .../share/timezonesets/ du répertoire d'installation (voir Section B.3, « Fichiers de configuration date/heure »).

Le paramètre de configuration timezone peut être fixé dans le fichier postgresql.conf ou par tout autre moyen standard décrit dans le Chapitre 17, Configuration du serveur. Il existe aussi quelques manières spéciales de le configurer :

  • si timezone n'est précisé ni dans postgresql.conf ni comme une option en ligne de commande du serveur, le serveur tente d'utiliser la valeur de la variable d'environnement TZ comme fuseau horaire par défaut. Si TZ n'est pas définie ou ne fait pas partie des noms de fuseau horaire connus par PostgreSQL™, le serveur tente de déterminer le fuseau horaire par défaut du système d'exploitation en vérifiant le comportement de la fonction localtime() de la bibliothèque C. Le fuseau horaire par défaut est sélectionné comme la correspondance la plus proche parmi les fuseaux horaires connus par PostgreSQL™ ;

  • la commande SQL SET TIME ZONE configure le fuseau horaire pour une session. C'est une autre façon d'indiquer SET TIMEZONE TO avec une syntaxe plus compatible avec les spécifications SQL ;

  • la variable d'environnement PGTZ, si le client la positionne, est utilisée par les applications fondées sur libpq pour envoyer une commande SET TIME ZONE au serveur lors de la connexion.