Jeudi 14 janvier 2010
4
14
/01
/Jan
/2010 02:16
Numérotation des semaines ISO 8601
C’est quoi l’ISO 8601 ? C’est une norme d’horodatation qui permet entre autres d’identifier une semaine au cours d’une
année. Elle définit une règle stricte de numérotation internationale (mise à part nos amis Canadiens et Américains).
Elle utilise le même cycle de sept jours par semaine que le calendrier grégorien.
Pourquoi cette norme ? Pouvoir s’organiser, planifier, synchroniser, consolider…
Que dit cette norme sur la numérotation de semaine (ISOWEEK, IW) ?
-
une semaine commence un Lundi ( j = 1 = Lundi)
-
les jours de la semaine sont numérotés de 1 à 7 ( j = 7 = Dimanche)
-
la semaine 1 est celle qui contient le premier Jeudi de l’année ( j= 4)
-
Une semaine ISO appartient tout entière à l'une ou l'autre année
Voilà, maintenant que vous connaissez un peu cette norme pour l’utilisation du numéro de semaine, voici un
exemple de fonction (ISO donc !!) avec en paramètres d’entrés un numéro de SEMAINE et une ANNEE qui va permettre de définir et de connaître la borne inferieure de cette semaine dans l’année (en gros la date au format DD/MM/YYYY).
ATTENTION à la
valeur du paramètre NLS_TERRITORY de votre session.
C’est important car suivant la valeur de votre NLS la semaine
commence soit un dimanche ou un lundi.
Pour connaitre la valeur du paramètre tapez
SQL> SELECT * FROM nls_session_parameters;
Pour changer la valeur du
NLS (attention si vous êtes en mode production !!!)
SQL> ALTER
SESSION SET nls_territory = 'FRANCE';
Ou
SQL> ALTER
SESSION SET nls_territory = 'AMERICA';
Si NLS_TERRITORY = ’FRANCE’ alors la valeur du jour Jeudi = 4 (Lundi à
Dimanche)
Si NLS_TERRITORY = ’AMERICA’ alors la valeur du jour Jeudi = 5 (Dimanche à Samedi)
CREATE OR REPLACE FUNCTION SEMAINE(SEM IN Integer,ANNEE IN Integer) RETURN DATE
IS
premier_jeudi_annee INTEGER;
jour INTEGER;
BEGIN
premier_jeudi_annee := -1;
jour := 0;
WHILE jour <> 5 -- 5 ou 4 suivant la valeur de jeudi dans votre
NLS
LOOP
premier_jeudi_annee := premier_jeudi_annee + 1;
jour :=
TO_CHAR(TO_DATE(ANNEE || '0101', 'YYYYMMDD') + premier_jeudi_annee, 'D');
END LOOP;
RETURN TO_DATE(ANNEE || '0101', 'YYYYMMDD')+(premier_jeudi_annee + (7 * (SEM - 2)) +4);
END SEMAINE;
/
On exécute des
requêtes pour valider
SQL> select SEMAINE(1,2010) from dual;
04/01/2010
SQL> select SEMAINE(1,2009) from dual;
29/12/2008
On vérifie à l’aide du format IW ( ISOWEEK )
SQL> select to_char(to_date('29/12/2008','DD/MM/YYYY'),'IW') from dual;
01
Variantes pour avoir la
borne inférieure + borne supérieure
SQL> select SEMAINE(1,2010) , (SEMAINE(1,2010) + 6) from dual;
04/01/2010 10/01/2010
SQL> select SEMAINE(1,2009) , (SEMAINE(1,2009) + 6) from dual;
29/12/2008 04/01/2009