#1 Wed 27 November 2013 12:39
- 0liv
- Participant occasionnel
- Date d'inscription: 27 Nov 2013
- Messages: 29
Gestion de la date Postgres/Postgis
Bonjour,
Je suis un peu bloqué sur un problème de date sur Postgres/PostGis, peut être que quelqu'un pourra m'aider ici.
Ma problématique est la suivante : je dois représenter des réglementations sous forme de périmètres géographiques. Ces réglementations sont en vigueur pour une certaines durée.
Exemple n°1: Du 1er juin 2013 au 30 avril 2014
Exemple n°2: Du 1er juin au 30 avril de chaque année
J'ai donc créé une table dans PostGis avec les périmètres des réglementations et leurs attributs ainsi que deux champs de type date qui indiquent la date de début et la date de fin. Je crée ensuite une vue avec comme condition que la date du jour soit comprise entre la date de début et la date de fin.
Code:
CREATE VIEW Test AS SELECT * FROM reglementation WHERE now() >= reglementation.date_debut AND now() <= reglementation.date_fin
Ceci me permet d'avoir une vue avec les réglementations en vigueur à la date actuelle pour les réglementations du type de l'exemple n°1.
Mon problème consiste donc à créer une vue issue d'une requête qui ne prenne pas en compte l'année, mais uniquement le jour et le mois. Est ce que cela est possible?
Merci.
Dernière modification par 0liv (Wed 27 November 2013 12:47)
Hors ligne
#2 Wed 27 November 2013 13:52
Re: Gestion de la date Postgres/Postgis
Bonjour,
vous pouvez extraire de toute date le numéro du jour de l'année correspondant :
Code:
select extract(doy FROM now()) < extract(doy from '2013-12-15'::date)
http://www.postgresql.org/docs/9.3/static/functions-datetime.html
Dans votre cas ça devrait donner ceci :
Code:
CREATE VIEW Test AS SELECT * FROM reglementation WHERE extract(doy FROM now())>= extract(doy FROM reglementation.date_debut) AND extract(doy FROM now())<= extract(doy FROM reglementation.date_fin)
Mathieu BOSSAERT
Association GeoRezo
Hors ligne
#3 Wed 27 November 2013 17:20
- Fritsch
- Participant occasionnel
- Lieu: Paris
- Date d'inscription: 8 Nov 2006
- Messages: 32
Re: Gestion de la date Postgres/Postgis
Attention, si on supprime la prise en compte du millésime, on se retrouve avec une année circulaire. La requête proposée par Mathieu B ne gère pas cette circularité, et ne fonctionnera donc pas pour une réglementation active (par exemple) du 1er décembre au 31 janvier.
Pour résoudre ce problème, d'abord une question sur votre MCD : comment faites vous la différence entre les deux cas :
Code:
Exemple n°1: Du 1er juin 2013 au 30 avril 2014 Exemple n°2: Du 1er juin au 30 avril de chaque année
Emmanuel.
Hors ligne
#4 Wed 27 November 2013 17:51
- 0liv
- Participant occasionnel
- Date d'inscription: 27 Nov 2013
- Messages: 29
Re: Gestion de la date Postgres/Postgis
Merci pour vos réponses,
J'ai en réalité deux tables:
- Une pour les réglementations du type de l'exemple un.
- Une autre pour le deuxième cas. Cette deuxième a exactement la même structure avec un champ "date_debut" et un champ "date_fin" au format jj/mm/aaaa.
Hors ligne
#5 Wed 27 November 2013 18:17
Re: Gestion de la date Postgres/Postgis
Attention, si on supprime la prise en compte du millésime, on se retrouve avec une année circulaire. La requête proposée par Mathieu B ne gère pas cette circularité, et ne fonctionnera donc pas pour une réglementation active (par exemple) du 1er décembre au 31 janvier.
Merci Emmanuel, en effet ça ne fonctionnera pas. Je suis en plein dans la gestion des date moi aussi avec PostgreSQL mais malheureusement pas encore très à l'aise avec ce type de données...
Mathieu BOSSAERT
Association GeoRezo
Hors ligne
#6 Thu 28 November 2013 11:04
- Fritsch
- Participant occasionnel
- Lieu: Paris
- Date d'inscription: 8 Nov 2006
- Messages: 32
Re: Gestion de la date Postgres/Postgis
Il y a un second problème, c'est que le doy est source de bug à cause des années bissextiles. Selon l'année (fictive) qui figure dans les dates début et fin, et selon l'année du now(), on peut avoir un décalage de 1 jour.
Si on considère cette source de bug comme négligeable, on règle le premier problème de la manière suivante :
Code:
CREATE VIEW Test AS SELECT * FROM reglementation WHERE (extract(doy FROM date_fin)-extract(doy FROM date_debut))*(extract(doy FROM now())-extract(doy FROM date_fin))*(extract(doy FROM now())-extract(doy FROM date_debut))<=0
Explication :
- si (fin-debut)>0, alors now doit appartenir au segment [debut;fin], et donc (now-debut) et (now_fin) sont de signes opposés
- si (fin-debut)<0, on est dans le cas décembre-janvier, et now doit être à l'extérieur du segment [debut;fin] : c'est la condition opposée de la précédente, i.e. (now-debut) et (now_fin) sont de même signe.
Dans les deux cas, le produit des trois différences doit être négatif.
- le cas "fin-debut=0" est évident, mais toujours avec la réserve que le doy est imprécis.
Hors ligne
#7 Thu 28 November 2013 14:38
- Fritsch
- Participant occasionnel
- Lieu: Paris
- Date d'inscription: 8 Nov 2006
- Messages: 32
Re: Gestion de la date Postgres/Postgis
Cette deuxième a exactement la même structure avec un champ "date_debut" et un champ "date_fin" au format jj/mm/aaaa.
jj/mm/aaaa ? Dans un champ texte ?
Si tel est le cas, la première chose à faire est de tout convertir dans des champs "date" :
UPDATE maTable SET date_debut2 = to_date(date_debut, 'DD/MM/YYYY')
Au minimum, cela garantit la cohérence des dates stockées.
Hors ligne
#8 Thu 28 November 2013 14:52
- Fritsch
- Participant occasionnel
- Lieu: Paris
- Date d'inscription: 8 Nov 2006
- Messages: 32
Re: Gestion de la date Postgres/Postgis
Ensuite, pour régler le problème, j'utiliserais EXTRACT pour construire un ordre universel des jours de l'année, en considérant fictivement que tous les mois peuvent avoir 40 jours.
Cela donne :
CREATE VIEW Test AS
SELECT uniquement les champs qui m'intéressent, et en particulier pas n, d, f.
FROM
( SELECT *,(EXTRACT('month' FROM now())) * 40 + EXTRACT('day' FROM now() ) AS n;
(EXTRACT('month' FROM date_debut)) * 40 + EXTRACT('day' FROM date_debut) AS d;
(EXTRACT('month' FROM date_fin )) * 40 + EXTRACT('day' FROM date_fin ) AS f;
FROM reglementation
WHERE (f-d)*(n-d)*(n-f)<=0)
) AS tmp
Disclaimer : proposition non testée, livrée brute de décoffrage.
Dernière modification par Fritsch (Mon 02 December 2013 11:43)
Hors ligne
#9 Thu 28 November 2013 17:00
- 0liv
- Participant occasionnel
- Date d'inscription: 27 Nov 2013
- Messages: 29
Re: Gestion de la date Postgres/Postgis
Merci beaucoup pour toutes ces réponses Emmanuel!
Concernant les champs contenant les dates, ils sont bien au format Date.
Ne m'attendant pas à obtenir une réponse aussi rapidement, je me suis lancé dans autre chose, j'aurais l'occasion de tester ta solution ce weekend, donc je vous dit ça rapidement!
Hors ligne