PostgreSQL supporte l'ensemble des types date et heure du SQL. Ces types sont présentés dans le Tableau 8.9. Les opérations disponibles sur ces types de données sont décrites dans la Section 9.9. Les dates sont comptées suivant le calendrier grégorien, même dans le cas des dates antérieures à l'introduction du calendrier (voir) Section B.6 pour plus d'informations).
Tableau 8.9. Types date et heure
Nom | Taille de stockage | Description | Valeur minimale | Valeur maximale | Résolution |
---|---|---|---|---|---|
timestamp [ ( | 8 octets | date et heure (sans fuseau horaire) | 4713 avant JC | 294276 après JC | 1 microseconde |
timestamp [ ( | 8 octets | date et heure, avec fuseau horaire | 4713 avant JC | 294276 après JC | 1 microseconde |
date | 4 octets | date seule (pas d'heure) | 4713 avant JC | 5874897 après JC | 1 jour |
time [ ( | 8 octets | heure seule (pas de date) | 00:00:00.00 | 24:00:00 | 1 microseconde |
time [ ( | 12 octets | heure (sans date), avec fuseau horaire | 00:00:00+1559 | 24:00:00-1559 | 1 microseconde |
interval [ | 16 octets | intervalles de temps | -178000000 années | 178000000 années | 1 microseconde |
Le standard SQL impose que timestamp
soit un équivalent de
timestamp without time zone
.
timestamptz
est accepté comme abréviation pour
timestamp with time zone
; c'est une extension
PostgreSQL.
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.
Le type interval
a une option supplémentaire, qui permet
de restreindre le jeu de champs stockés en écrivant une de ces
expressions :
YEAR MONTH DAY HOUR MINUTE SECOND YEAR TO MONTH DAY TO HOUR DAY TO MINUTE DAY TO SECOND HOUR TO MINUTE HOUR TO SECOND MINUTE TO SECOND
Notez que si champs
et
p
sont tous les deux indiqués,
champs
doit inclure SECOND
,
puisque la précision s'applique uniquement aux secondes.
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.
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 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.7 peut être consultée pour plus d'information. SQL requiert la syntaxe suivante :
type
[ (p
) ] 'valeur
'
où p
, précision optionnelle, est un entier
correspondant au nombre de décimales du champ secondes.
La précision peut être spécifiée pour les types time
,
timestamp
et interval
, et peut aller de 0 à 6.
Si aucune précision
n'est indiquée dans une déclaration de constante, celle de la valeur
littérale est utilisée (mais pas plus de 6 chiffres).
Le Tableau 8.10 regroupe les formats
de date possibles pour la saisie de valeurs de type date
.
Tableau 8.10. Saisie de date
Exemple | Description |
---|---|
1999-01-08 | ISO-8601 ; 8 janvier, quel que soit le mode (format recommandé) |
January 8, 1999 | sans ambiguïté quel que soit le style de date
(datestyle ) |
1/8/1999 | 8 janvier en mode MDY ;
1er août en mode DMY |
1/18/1999 | 18 janvier en mode MDY ;
rejeté dans les autres modes |
01/02/03 | 2 janvier 2003 en mode MDY ;
1er février 2003 en mode DMY ;
3 février 2001 en mode YMD
|
1999-Jan-08 | 8 janvier dans tous les modes |
Jan-08-1999 | 8 janvier dans tous les modes |
08-Jan-1999 | 8 janvier dans tous les modes |
99-Jan-08 | 8 janvier en mode YMD , erreur sinon |
08-Jan-99 | 8 janvier, sauf en mode YMD : erreur |
Jan-08-99 | 8 janvier, sauf en mode YMD : erreur |
19990108 | ISO-8601 ; 8 janvier 1999 dans tous les modes |
990108 | ISO-8601 ; 8 janvier 1999 dans tous les modes |
1999.008 | Année et jour de l'année |
J2451187 | Date du calendrier Julien |
January 8, 99 BC | Année 99 avant Jésus Christ |
Les types « heure du jour » sont
time [ (
et
p
) ] without time zonetime [ (
.
p
) ] with time zonetime
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 et le Tableau 8.12). 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
et est affiché de la façon dont il est
stocké ; il n'est pas converti vers le fuseau horaire actif.
Tableau 8.11. Saisie d'heure
Exemple | Description |
---|---|
04:05:06.789 | ISO 8601 |
04:05:06 | ISO 8601 |
04:05 | ISO 8601 |
040506 | ISO 8601 |
04:05 AM | Identique à 04:05 ; AM n'affecte pas la valeur |
04:05 PM | Identique à 16:05 ; l'heure doit être <= 12 |
04:05:06.789-8 | ISO 8601, avec le décalage UTC comme fuseau horaire |
04:05:06-08:00 | ISO 8601, avec le décalage UTC comme fuseau horaire |
04:05-08:00 | ISO 8601, avec le décalage UTC comme fuseau horaire |
040506+0730 | ISO 8601, avec le décalage UTC avec un fuseau horaire en heure fractionnée |
040506+07:30:00 | décalage UTC exprimé en secondes (non autorisé dans ISO 8601) |
040506-08 | ISO 8601 |
04:05:06 PST | fuseau horaire abrégé |
2003-04-12 04:05:06 America/New_York | fuseau horaire en nom complet |
Tableau 8.12. Saisie des fuseaux horaires
Exemple | Description |
---|---|
PST | Abréviation pour l'heure standard du Pacifique (Pacific Standard Time) |
America/New_York | Nom complet du fuseau horaire |
PST8PDT | Nommage POSIX du fuseau horaire |
-8:00:00 | Décalage UTC pour la zone PST |
-8:00 | Décalage ISO-8601 pour la zone PST (format étendu ISO 8601) |
-800 | Décalage ISO-8601 pour la zone PST (format basique ISO 8601) |
-8 | Décalage ISO-8601 pour la zone PST (format basique ISO 8601) |
zulu | Abréviation militaire de GMT |
z | Version courte de zulu (aussi dans ISO 8601) |
La Section 8.5.3 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 libellés
timestamp without time zone
et
timestamp with time zone
par la présence d'un symbole
« + » ou d'un « - » et le décalage du fuseau horaire
après l'indication du temps. 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).
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.
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.
Tableau 8.13. Saisie de dates/heures spéciales
Saisie | Types valides | Description |
---|---|---|
epoch | date , timestamp | 1970-01-01 00:00:00+00 (date système zéro d'Unix) |
infinity | date , timestamp | plus tard que toutes les autres dates |
-infinity | date , timestamp | plus tôt que toutes les autres dates |
now | date , time , timestamp | heure de démarrage de la transaction courante |
today | date , timestamp | aujourd'hui minuit (00:00 ) |
tomorrow | date , timestamp | demain minuit (00:00 ) |
yesterday | date , timestamp | hier minuit (00:00 ) |
allballs | time | 00:00:00.00 UTC |
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
. (Voir
la Section 9.9.4). Ce
sont là des fonctions SQL qui ne sont pas reconnues
comme chaînes de saisie de données.
Bien qu'il n'y ait pas de problèmes à utiliser les chaînes
now
, today
,
tomorrow
et yesterday
dans des
commandes SQL interactives, elles peuvent avoir un comportement
surprenant quand la commande est sauvegardée pour une exécution
ultérieure, par exemple dans des requêtes préparées, des vues ou des
fonctions. La chaîne peut être convertie en une valeur spécifique qui
continue à être utilisée bien après qu'elle ne soit obsolète. Dans de
tels contextes, utilisez plutôt une des fonctions SQL. Par exemple,
CURRENT_DATE + 1
est plus sûr que
'tomorrow'::date
.
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 (date au format
Unix date) ou German (germanique). 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 mal choisi, un accident
historique.) Le Tableau 8.14 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. Néanmoins, le style
POSTGRES affiche seulement les dates dans le
format ISO.
Tableau 8.14. Styles d'affichage de date/heure
Spécification de style | Description | Exemple |
---|---|---|
ISO | standard SQL ISO 8601 | 1997-12-17 07:37:16-08 |
SQL | style traditionnel | 12/17/1997 07:37:16.00 PST |
Postgres | style original | Wed Dec 17 07:37:16 1997 PST |
German | style régional | 17.12.1997 07:37:16.00 PST |
ISO 8601 spécifie l'utilisation d'une lettre T
en
majuscule pour séparer la date et l'heure.
PostgreSQL accepte ce format en entrée. En
sortie, il utilise un espace plutôt qu'un T
, comme
indiqué ci-dessus. C'est à la fois plus lisible et cohérent avec la
RFC 3339 ainsi qu'avec d'autres systèmes de bases de données.
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 pour savoir comment ce paramètre affecte l'interprétation des valeurs en entrée). Le Tableau 8.15 présente des exemples.
Tableau 8.15. Convention de présentation des dates
Valeur de datestyle (style de date) | Ordre de saisie | Exemple d'affichage |
---|---|---|
SQL, DMY | jour /mois /année | 17/12/1997 15:37:16.00 CET |
SQL, MDY | mois /jour /année | 12/17/1997 07:37:16.00 PST |
Postgres, DMY | jour /mois /année | Wed 17 Dec 07:37:16 1997 PST |
Dans le style ISO, le fuseau horaire est toujours
affiché sous la forme d'un décalage numérique signé de UTC, avec un
signe positif utilisé pour les zones à l'est de Greenwich. Le décalage
sera affiché sous la forme hh
(heures seulement) s'il s'agit d'un nombre intégral d'heures, ou sous la
forme hh
:mm
s'il
s'agit d'un nombre intégral de minutes, et enfin sous la forme
hh
:mm
:ss
.
(Le troisième cas n'est pas possible pour tout standard moderne de
fuseau horaire, mais il peut apparaître en travaillant sur des jours
antérieurs à l'adoption des fuseaux horaires standardisés.) Pour les
autres styles de dates, le fuseau horaire est affiché comme une
abréviation alphabétique si l'une d'entre elles est d'utilisation
commune dans le fuseau actuel. Sinon, il apparaît comme un décalage
numérique signé dans le format basique ISO 8601
(hh
ou hhmm
).
Le style de date/heure peut être sélectionné à 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) permet de formater les affichages
de date/heure de manière plus flexible.
Les fuseaux horaires et les conventions liées sont influencés 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 utilise la très répandue base de données de fuseaux horaires IANA (Olson) pour gérer les informations sur les règles historiques de fuseau horaire. Pour les dates se situant dans le futur, PostgreSQL part de l'assomption que les dernières règles connues pour un fuseau continueront à s'appliquer dans le futur.
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
ne puisse pas se voir associer un
fuseau horaire, 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ées 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 51.92).
PostgreSQL utilise les données
IANA 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 51.91). Les paramètres de configuration
TimeZone et log_timezone ne
peuvent pas être configurés à l'aide
d'une abréviation de fuseau horaire, mais ces abréviations peuvent
être utilisées dans les saisies de date/heure et avec l'opérateur
AT TIME ZONE
;
En plus des noms et abréviations des fuseaux horaires, PostgreSQL accepte les spécifications de fuseau horaire du style POSIX, comme décrit dans Section B.5. Cette option n'est habituellement pas préférable à utiliser un nom de fuseau horaire, mais cela pourrait se révéler nécessaire si aucune entrée adéquate de fuseau horaire n'est disponible dans la base IANA.
Les abréviations représentent un décalage spécifique depuis UTC, alors
qu'un grand nombre des noms complets implique une règle de changement
d'heure, et donc potentiellement deux décalages UTC. Par exemple,
2014-06-04 12:00 America/New_York
représente minuit à
New York, ce qui, pour cette date particulière, sera le fuseau Eastern
Daylight Time (UTC-4). Donc 2014-06-04 12:00 EDT
stipule
ce moment précis. Mais 2014-06-04 12:00 EST
représente
minuit pour le fuseau Eastern Standard Time (UTC-5), quel que soit le
changement d'heure en effet à cette date.
Pour compliquer encore plus, certaines juridictions ont utilisé les mêmes
abréviations de fuseau horaire pour signifier des décalages UTC différents.
Par exemple, Moscow MSK
correspondait à UTC+3 certaines
années et UTC+4 à d'autres. PostgreSQL interprète
ces abréviations suivant ce à quoi elles correspondent (ou ont correspondu
récemment) pour la date indiquée. Mais, comme le montre l'exemple
EST
ci-dessus, ce n'est pas nécessairement la même chose
que l'heure civile locale à ce moment.
Dans tous les cas, les noms et les abréviations 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 ni les abréviations des fuseaux horaires 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.4).
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 19.
Il existe aussi quelques manières spéciales de le configurer :
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
est utilisée par les
applications clientes fondées sur
libpq pour envoyer une commande
SET TIME ZONE
au serveur lors de la connexion.
Les valeurs de type interval
peuvent être saisies en utilisant
la syntaxe verbeuse suivante :
[@]quantité
unité
[quantité
unité
...] [direction
]
où quantité
est un nombre (éventuellement signé) ;
unité
est microsecond
millisecond
, second
,
minute
, hour
, day
,
week
, month
, year
,
decade
, century
, millennium
,
ou des abréviations ou pluriels de ces unités ;
direction
peut être ago
(pour indiquer
un intervalle négatif) ou vide. Le signe @
est du bruit optionnel.
Les quantités de chaque unité différente sont implicitement ajoutées, avec prise en compte
appropriée des signes (+
et -
). ago
inverse tous les champs. Cette syntaxe est aussi utilisée pour les sorties d'intervalles, si
IntervalStyle est positionné à postgres_verbose
.
Les quantités de jours, heures, minutes et secondes peuvent être spécifiées sans
notations explicites d'unités. Par exemple '1 12:59:10'
est
comprise comme '1 day 12 hours 59 min 10 sec'
. Par ailleurs,
une combinaison d'années et de mois peut être spécifiée avec un tiret ;
par exemple, '200-10'
est compris comme '200 years
10 months'
. (Ces formes raccourcies sont en fait les seules autorisées
par le standard SQL, et sont utilisées pour la sortie quand
la variable IntervalStyle
est positionnée à
sql_standard
.)
Les valeurs d'intervalles peuvent aussi être écrites en tant qu'intervalles de temps ISO 8601, en utilisant soit le « format avec désignateurs » de la section 4.4.3.2 ou le « format alternatif » de la section 4.4.3.3. Le format avec désignateurs ressemble à ceci :
Pquantité
unité
[quantité
unité
...] [ T [quantité
unité
...]]
La chaîne doit commencer avec un P
, et peut inclure un
T
qui introduit les unités de ce type. Les abréviations
d'unité disponibles sont données dans Tableau 8.16. Des unités peuvent être omises,
et peuvent être spécifiées dans n'importe quel ordre, mais les unités inférieures
à un jour doivent apparaître après T
. En particulier, la signification
de M
dépend de son emplacement, c'est-à-dire avant ou après
T
.
Tableau 8.16. Abréviations d'unités d'intervalle ISO 8601
Abréviation | Signification |
---|---|
Y | Années |
M | Mois (dans la zone de date) |
W | Semaines |
D | Jours |
H | Heures |
M | Minutes (dans la zone de temps) |
S | Secondes |
Dans le format alternatif :
P [années
-mois
-jours
] [ Theures
:minutes
:secondes
]
la chaîne doit commencer par P
, et un T
sépare la zone de date et la zone de temps de l'intervalle.
Les valeurs sont données comme des nombres, de façon similaire aux dates ISO 8601.
Lors de l'écriture d'une constante d'intervalle avec une spécification de
champs
, ou lors de l'assignation d'une chaîne à
une colonne d'intervalle qui a été définie avec une spécification de
champs
, l'interprétation de quantité sans unité
dépend des champs
. Par exemple,
INTERVAL '1' YEAR
est interprété comme 1 an, alors que
INTERVAL '1'
est interprété comme 1 seconde. De plus,
les valeurs du champ « à droite » du champ le moins significatif
autorisé par la spécification de champs
sont
annulées de façon silencieuse. Par exemple, écrire INTERVAL '1 day
2:03:04' HOUR TO MINUTE
implique la suppression du champ des
secondes, mais pas celui des journées.
D'après le standard SQL, toutes les valeurs de tous les champs
d'un intervalle doivent avoir le même signe, ce qui entraîne qu'un signe négatif
initial s'applique à tous les champs ; par exemple, le signe négatif dans
l'expression d'intervalle '-1 2:03:04'
s'applique à la fois aux
jours et aux heures/minutes/secondes. PostgreSQL permet
que les champs aient des signes différents, et traditionnellement traite chaque champ
de la représentation textuelle comme indépendamment signé, ce qui fait que la partie
heure/minute/seconde est considérée comme positive dans l'exemple. Si
IntervalStyle
est positionné à sql_standard
,
alors un signe initial est considéré comme s'appliquant à tous les champs (mais
seulement si aucun autre signe n'apparaît).
Sinon, l'interprétation traditionnelle de PostgreSQL
est utilisée. Pour éviter les ambiguïtés, il est recommandé d'attacher un signe
explicite à chaque partie, si au moins un champ est négatif.
Les valeurs des champs peuvent avoir des parties fractionnelles :
par exemple, '1.5 weeks'
ou
'01:02:03.45'
. Néanmoins, comme l'intervalle stocke
en interne seulement les trois unités sous forme d'entier (mois, jours,
microsecondes), les unités fractionelles doivent être divisées en plus
petites unités. Les parties fractionnelles des unités supérieures aux
mois est tronquées en un nombre entier de mois, par exemple
'1.5 years'
devient '1 year 6
mons'
. Les parties fractionnelles des semaines et jours sont
calculées comme un nombre entier de jours et de microsecondes, en
supposant 30 jours par mois et 24 heures par jour, par exemple
'1.75 months'
devient 1 mon 22 days
12:00:00
. Seules les secondes seront affichées en fractionné
en sortie.
Tableau 8.17 présente des exemples de saisies
d'interval
valides.
Tableau 8.17. Saisie d'intervalle
Exemple | Description |
---|---|
1-2 | Format SQL standard : 1 an 2 mois |
3 4:05:06 | Format SQL standard : 3 jours 4 heures 5 minutes 6 secondes |
1 year 2 months 3 days 4 hours 5 minutes 6 seconds | Format PostgreSQL traditionnel : 1 an 2 mois 3 jours 4 heures 5 minutes 6 secondes |
P1Y2M3DT4H5M6S | « format avec désignateurs » ISO 8601 : signification identique à ci-dessus |
P0001-02-03T04:05:06 | « format alternatif » ISO 8601 : signification identique à ci-dessus |
En interne, les valeurs interval
sont enregistrées comme des
mois, jours et microsecondes. C'est fait ainsi parce que le nombre de jours
dans un mois varie, et un jour peut avoir 23 ou 25 heures s'il y a eu un
changement d'heure. Les champs mois et jours sont des entiers, alors que
le champ des microsecondes peut contenir des secondes fractionnelles.
Comme les intervalles
sont habituellement créés à partir de chaînes constantes ou de
soustractions de timestamp
, cette méthode de stockage
fonctionne bien dans la plupart des cas, mais peut être la cause de
résultats inattendus :
SELECT EXTRACT(hours from '80 minutes'::interval); date_part ----------- 1 SELECT EXTRACT(days from '80 hours'::interval); date_part ----------- 0
Les fonctions justify_days
et
justify_hours
sont disponibles pour ajuster les
jours et heures qui dépassent l'étendue normale.
Le format de sortie du type interval peut être positionné à une de ces quatre
valeurs : sql_standard
, postgres
,
postgres_verbose
ou iso_8601
,
en utilisant la commande SET intervalstyle
.
La valeur par défaut est le format postgres
.
Tableau 8.18 donne des exemples de chaque style de
format de sortie.
Le style sql_standard
produit une sortie qui se conforme
à la spécification du standard SQL pour les chaînes littérales d'intervalle, si
la valeur de l'intervalle reste dans les restrictions du standard (soit
année-mois seul, ou jour-temps seul, et sans mélanger les composants positifs
et négatifs). Sinon, la sortie ressemble au standard littéral année-mois
suivi par une chaîne jour-temps littérale, avec des signes explicites ajoutés
pour désambiguer les intervalles dont les signes seraient mélangés.
La sortie du style postgres
correspond à la sortie des
versions de PostgreSQL précédant la 8.4, si le
paramètre datestyle était positionné à
ISO
.
La sortie du style postgres_verbose
correspond à la sortie
des versions de PostgreSQL précédant la 8.4, si le
paramètre datestyle était positionné à autre chose que
ISO
.
La sortie du style iso_8601
correspond au « format
avec designateurs » décrit dans la section 4.4.3.2 du standard ISO 8601.
Tableau 8.18. Exemples de styles d'affichage d'intervalles
Spécification de style | Intervalle année-mois | Intervalle date-temps | Interval Mixte |
---|---|---|---|
sql_standard | 1-2 | 3 4:05:06 | -1-2 +3 -4:05:06 |
postgres | 1 year 2 mons | 3 days 04:05:06 | -1 year -2 mons +3 days -04:05:06 |
postgres_verbose | @ 1 year 2 mons | @ 3 days 4 hours 5 mins 6 secs | @ 1 year 2 mons -3 days 4 hours 5 mins 6 secs ago |
iso_8601 | P1Y2M | P3DT4H5M6S | P-1Y-2M3DT-4H-5M-6S |