Vous n'êtes pas identifié(e).
Bonjour à tous,
Je travaille sur une base 8.4 sous CentOS.
Je souhaite écrire une fonction qui :
prend en paramètre un N° de semaine
retour la date correspondant au 1er jour (lundi) de cette semaine.
J'ai trouvé la fonction pour calculer un N° de semaine à partir d'une date:
SELECT EXTRACT(week FROM $1::date)::integer INTO nNoSem;
Mais je ne sais pas comment retourner la date du lundi de cette semaine.
Merci pour votre aide.
Hors ligne
J'ai une solution, mais je la trouve peu élégante. Si quelqu'un a mieux, qu'il n'hésite pas
Disons que je cherche la 13e semaine de 2010:
SELECT date_trunc('week','2010-01-04'::date) + '12 weeks'::interval;
La raison est que la première semaine d'une année, c'est la semaine contenant le 4 janvier. Je trouve donc le premier jour de cette semaine, qui est donc le premier jour de la semaine 1. Et je lui ajoute un intervalle correspondant au nombre de semaines manquants…
Marc.
Hors ligne
Bonjour,
Merci pour la réponse.
A force de chercher, j'ai écrit ceci :
SELECT to_char(to_date(substr(to_char(current_date,''YYYY''),1,2)||SUBSTR($1,1,2)||''-''||SUBSTR($1,3,2)||''-1'', ''IYYY-IW-ID''),''YYYYMMDD'');
En entrée, je prends un N° de semaine au format YYWW, par exemple nous sommes en semaine 49 de l'année 2010, donc 1049.
J'ai fait plusieurs tests, cela semble fonctionner.
Hors ligne
Histoire de faire propre, pourquoi ne pas prendre un numéro d'années entier, et un numéro de mois, les deux séparés dans deux paramètres différents ?
Histoire de ne pas refaire les mêmes erreurs que les développeurs cobol des années 70…
Marc.
Hors ligne
Bonjour Marc,
Peux-tu m'expliquer plus clairement ?
Merci.
Hors ligne
Ce que je veux dire, c'est qu'il serait plus logique de passer deux paramètres :
le mois (01 à 12, numérique) et l'année (numérique aussi). Ça veut dire que d'emblée, on a une fonction qui marche sur toutes les plages de dates, sur laquelle on n'est pas obligé de bidouiller pour redécouper des chaînes de caractères qui n'auraient jamais du être collées ensembles, et qui peut vérifier que les types passés en paramètre sont bons (ce qui évite à l'utilisateur qui l'a mal appelée de devoir aller regarder dans le code pourquoi il a une erreur à la ligne 12).
C'est le genre d'habitudes qui rend le code plus robuste.
Le prototype de la fonction serait donc plutôt create function ma_fonction (annee integer, mois integer) returns date
Marc.
Hors ligne
Marc,
Je pense que tu veux dire semaine et non pas mois ?
En paramètre, il s'agit du N° de semaine dans l'année, par exemple nous sommes en semaine 49 de l'année 2010, donc 1049.
Tu me conseille donc de prendre 2 paramètres (Année, N°semaine) pour éviter le découpage dans la fonction ?
Merci pour ton aide.
Hors ligne
Oui, semaine, bien sûr.
Marc.
Hors ligne
Bonjour,
attention l'extraction de l'année de la premiere semaine peut poser problême :
exemple :
select extract(year from to_date('2010-01-01','YYYY-MM-DD')) donne 2010 alors qu'il s'agit en fait de la 53 semaine de l'année 2009 d'ou la demande d'isoyear :
select extract(isoyear from to_date('2010-01-01','YYYY-MM-DD')) qui donnera bien 2009
Voila ma (une) solution:
select to_date(extract(isoyear from to_date('2010-01-04','YYYY-MM-DD'))::text||to_char(extract(week from to_date('2010-01-04','YYYY-MM-DD')),'FM09')||'1','IYYYIWID')
select to_date(extract(isoyear from to_date('2010-01-01','YYYY-MM-DD'))::text||to_char(extract(week from to_date('2010-01-01','YYYY-MM-DD')),'FM09')||'1','IYYYIWID')
Dernière modification par meles (08/12/2010 13:50:35)
Hors ligne
Ça ne répond pas à la question, qui est de trouver le premier jour de la semaine d'une semaine et année passées en paramètres.
Je pense que la solution que j'ai proposée au départ est la plus sûre: elle s'appuie sur le mécanisme de gestion des dates interne à PostgreSQL, sans opérations de concaténation, et conversions multiples de formats, comme celles présentées depuis.
Si on imagine qu'on a passé deux paramètres à la fonction (je vais les appeler $1 et $2 )
Il suffit de renvoyer le résultat de "SELECT date_trunc('week',($1||'-01-04')::date) + ($2-1) * '1 week'::interval;
Marc.
Hors ligne
Ooops,
effectivement , j'avais intégré qu'il fallait donner le premier jour de la semaine pour une date donnée.
Un simple to_date('201001'||'1','IYYYIWID') ou '201001' est "l'année semaine" devrait alors faire l'affaire, non ?
Cordialement
Hors ligne
Oui, je me sens un peu con de ne pas y avoir pensé
ou encore plus léger : to_date('201002','IYYYIW'); ?
On n'a pas vraiment besoin du reste je pense…
Marc.
Hors ligne
Effectivement,
pas la peine de concaténer le '1' pour avoir le premier jour de la semaine.
Je penses qu'on va avoir du mal à faire plus léger :-).
Il n'est même pas utile d'écrire une fonction.
Et en plus ça m'a permis de découvrir les subtilités IYYY et YYYY (on a pas le droit de mélanger de l'iso et du grégorien dans le formatage, donc il a fallu relire la doc et c'est la que j'ai découvert IYYY)
Cordialement
Hors ligne
Super.
Vraiment trés court et puissant.
J'ai tout de même besoin d'une fonction car utilisé dans du PHP.
Merci encore.
Hors ligne