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

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

comment connaître le numéro d'une semaine en fonction d'une date et vis-versa ?


Sujet :

Python

  1. #1
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 423
    Points : 874
    Points
    874
    Par défaut comment connaître le numéro d'une semaine en fonction d'une date et vis-versa ?
    bonjour,

    j'aimerai connaître comment faire pour trouver le numéro d'une semaine en fonction d'une date ?

    et aussi les 7 jours d'une semaine dont je connais le numéro !

    Pas moyen de trouver cela dans la class datetime !

    Est-ce un traitement typiquement français de compter d'attribuer un numéro de semaine dans le calendrier ?

    une aide ?

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    C'est bel et bien dans la classe datetime :
    datetime.datetime.isocalendar
    Les explications sont données ici : datetime.date.isocalendar
    Le numéro de la semaine est le deuxième élément du triplet.

  3. #3
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 423
    Points : 874
    Points
    874
    Par défaut ok
    ah oui ! merci !
    j'avais à moitié raison, comme c'est dans la partie ISO, c'est que Européen ce genre de traitement !


    par contre la fonction ne fait pas l'inverse, me dire quels sont les 7 jours de la semaine 41 !

  4. #4
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Un peu de calcul te permettra de les trouver !
    Tu pars du lundi de la semaine 1 (facile à trouver), et tu ajoutes un timedelta correspondant au nombre de jours voulu.

  5. #5
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Pour lister la semaine 10
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from datetime import date,timedelta
    d=date(2009, 1, 1)
    unjour=timedelta(days=1)
    iso=d.isocalendar()
    while iso[1]!=10:
       d+=unjour
       iso=d.isocalendar()
    while iso[1]==10:
       print d
       d+=unjour
       iso=d.isocalendar()

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Sinon, pour faire ça en appliquant une formule :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    from datetime import date, timedelta
     
    def semaine(annee, sem):
        ref = date(annee, 1, 4) # Le 4 janvier est toujours en semaine 1
        j = ref.weekday()
        jours = 7*(sem - 1) - j
        lundi = ref + timedelta(days=jours)
        return [lundi + timedelta(days=n) for n in xrange(7)]

  7. #7
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Ah !!
    Je viens de mettre au point la même solution que oiffrig après deux heures de recherche.
    Tant pis, je la mets quand même, il y a quelques explications en plus.

    Je reprends son appellation de 'référence' pour le 4 Janvier

    ---------------------------

    La semaine 01 est toujours la semaine du 4 Janvier:
    http://fr.wikipedia.org/wiki/Num%C3%...O_des_semaines

    weekday() renvoie l'identité du jour sous forme d'un entier:
    Monday=0, Tuesday=1, Wednesday=2, Thursday=3, Friday=4, Sarurday=5, Sunday=6.

    J'appelle iso-premier le premier jour d'une année ISO.
    Si le 4 Janvier est un Lundi, l'iso-premier est le 4 Janvier.
    Si le 4 Janvier est un Mardi, l'iso-premier est le 3 Janvier, soit 1 jour avant.
    Si le 4 Janvier est un Mecredi, l'iso-premier est le 2 Janvier, soit 2 jours avant.
    Si le 4 Janvier est un Jeudi, l'iso-premier est le 1 Janvier, soit 3 jours avant.
    Si le 4 Janvier est un Vendredi, l'iso-premier est le 31 Décembre, soit 4 jours avant.
    Si le 4 Janvier est un Samedi, l'iso-premier est le 30 Décembre, soit 5 jours avant.
    Si le 4 Janvier est un Dimanche, l'iso-premier est le 29 Décembre, soit 6 jours avant.
    Donc l'iso-premier est (4 Janvier ).weekday() jours avant la référence qu'est le 4 Janvier.

    C'est timedelta() qui permet de faire des décalages temporels. Donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iso_premier = isoref4J - timedelta(isoref4J .weekday())
    Pour trouver les jours d'une semaine, c'est alors facile: on part de iso-premier et on rajoute des jours en fonction du numéro de semaine voulue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iso_premier + timedelta((sem-1)*7 + j)
    C'est (semaine-1) car pour obtenir la semaine 1, on ne rajoute rien du tout pour atteindre le premier de la semaine.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def les_7jours_de(an,sem):
        ref4J = date(an, 1, 4)
        x = ref4J.weekday()
        iso_premier = ref4J - timedelta(x)
        for j in xrange(7):
            print iso_premier + timedelta((sem-1)*7 + j)
    Un peu plus condensé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def les_7jours_de(an,sem):
        ref4J = date(an, 1, 4)
        for j in xrange(7):
            print ref4J  -  timedelta( ref4J.weekday())  +  timedelta((sem-1)*7 + j )

  8. #8
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 423
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 423
    Points : 874
    Points
    874
    Par défaut
    Citation Envoyé par Zavonen Voir le message
    Pour lister la semaine 10
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    from datetime import date,timedelta
    d=date(2009, 1, 1)
    unjour=timedelta(days=1)
    iso=d.isocalendar()
    while iso[1]!=10:
       d+=unjour
       iso=d.isocalendar()
    while iso[1]==10:
       print d
       d+=unjour
       iso=d.isocalendar()
    merci à tous pour votre aide et surtout oiffrig !

    par contre , la solution de Zavonen fonctionne aussi mais elle occupera grave le serveur si je cherche les jours des semaines de fin d'année !

  9. #9
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    mais elle occupera grave le serveur si je cherche les jours des semaines de fin d'année !
    As-tu essayé ?
    Moi je n'ai pas vu (à l'oeil) la différence entre la semaine 1 et la semaine 50, c'est pourquoi je n'ai pas proposé une formule. Mais oui, une formule c'est mieux c'est indiscutable.
    Python 2.6.1 sur linux-ubuntu 9.04 PC Intel dual-core

  10. #10
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut
    Juste une toute petite modif, pour éviter et la (grande..) boucle et la formule. Mais je n'ai rien contre la formule, bien au contraire.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from datetime import date,timedelta
    n=10
    d=date(2009, 1, 1)
    unjour=timedelta(days=1)
    bigjump=timedelta(days=(n-2)*7)
    d+=bigjump #pour éviter une longue boucle
    iso=d.isocalendar()
    while iso[1]!=n:
       d+=unjour
       iso=d.isocalendar()
    while iso[1]==n:
       print d
       d+=unjour
       iso=d.isocalendar()

  11. #11
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Les codes de Zavonen ont le défaut de ne pas être instantanément compréhensibles.

    Le premier code était en outre boiteux puisque en y remplaçant 10 par 1 pour afficher la semaine 1 on obtient:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> 
    2009-01-01
    2009-01-02
    2009-01-03
    2009-01-04
    >>>
    Ce n’est plus le cas avec son code modifié, dans le message précédent, parce que ce code commence par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    d=date(an, 1, 1)
    bigjump=timedelta(days=(n-2)*7)
    d+=bigjump
    ce qui, dans le cas où n (iso-numéro de la semaine) est 1, positionne d sur le 25 Décembre de l’année précédente.

    Or la semaine iso1 d’une année ne commence jamais avant le 29 Décembre de l’année précédente.
    Ce qui veut dire qu’en partant du 25 Décembre avec n=1 pour faire d += timedelta(1) , on commence toujours avec un d.isocalendar()[1] (l’iso-numéro de semaine de d) qui est différent de 1 (égal en fait à 52 ou 53 selon les années). Faire ensuite d += timedelta(1) et s’arrêter quand d.isocalendar()[1] devient 1 positionne effectivement ensuite d sur le Lundi de la semaine iso-1.


    ----------------------------------


    Donc les codes de Zavonen ne me plaisent pas trop.
    Mais le code d’oiffrig et le mien ne me paraissent en définitive guère moins reprochables.
    Pourquoi soustraire date(annee,1,4 janvier).weekday() ?
    Pourquoi additionner (sem-1)*7 jours et non pas sem*7 ?
    Il faut prendre un temps de réflexion, crayon en main, pour le comprendre.

    Il faut aussi savoir que le 4 Janvier est toujours en semaine iso1 de l’iso-calendrier. Sur ce point, la solution de Zavonen a au moins l’avantage que ce renseignement n’est pas nécessaire au départ de son algorithme; sauf qu’il faut quand même savoir que la semaine iso1 d’une année peut commencer l’année commune précedente. Il faut quand même bien savoir au moins un peu ce qu’est l’iso-calendrier au départ si on veut faire un tel code......


    Enfin bref, aucun des codes précédents n’est très immédiatement compréhensible. Le mien qui verse dans la formule est même assez hermétique. À y réléchir, j’ai même trouvé que le code de Zavonen a quelque chose de plus naturel dans son principe parce qu’il cherche à faire des += timedelta() correspondant à des progressions dans le calendrier qu’on saisit assez bien.


    ------------------------------------------


    Alors j’ai réfléchi et je trouve finalement préférable de procéder comme suit:

    Dire que le 4 janvier est toujours dans la semaine iso1 traduit le fait que
    les semaines iso1 peuvent être seulement l’une des suivantes:
    Lundi 29/12 au Dimanche 04/01
    Lundi 30/12 au Dimanche 05/01
    Lundi 31/12 au Dimanche 06/01
    Lundi 01/01 au Dimanche 07/01
    Lundi 02/01 au Dimanche 08/01
    Lundi 03/01 au Dimanche 09/01
    Lundi 04/01 au Dimanche 10/01

    c’est à dire que le Lundi iso1 peut donc tomber seulement l’un des jours du 29 Décembre au 4 Janvier.
    Donc la semaine iso1 commence toujours l’un des 7 jours à partir du 29/12.



    On peut déduire aussi que
    les semaines iso0 possibles sont:
    Lundi 22/12 au Dimanche 28/12
    Lundi 23/12 au Dimanche 29/12
    Lundi 24/12 au Dimanche 30/12
    Lundi 25/12 au Dimanche 31/12
    Lundi 26/12 au Dimanche 01/01
    Lundi 27/12 au Dimanche 02/01
    Lundi 28/12 au Dimanche 03/01


    Bien sûr, je sais bien que dans la définitions des iso-années, il n’y a pas de semaine iso-zéro.
    Mais je m’autorise la fantaisie d’appeler ainsi la semaine qui précède la semaine iso1 parce que c’est une notion bien pratique.


    Elle représente en effet le départ du décompte des vraies iso-semaines, celles de l’iso-année qui nous intéresse réellement. Or quand on compte, on le fait bien à partir de zéro et il est intéressant de savoir où est le zéro, non ?

    On peut résumer le fait que le Lundi de la semaine iso0 est l’un des 7 jours situés du 22 au 28 Décembre en disant que la semaine iso0 d’une iso-année commence au plus tôt le 22 Décembre de l’année commune précédente.

    Dès lors, pour déterminer quel jour précis est-ce, il suffit de faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        d = date(annne-1,12,22)
        while d.weekday():
            d += timedelta(1)
    Ce while est dans l’esprit du code de Zavonen. C'est moins performant (3 picosecondes en plus )qu'une formule puisque ça exécute plusieurs fois la même action, mais je préfère parce que c’est plus instantanément compréhensible.

    Une fois qu’on a ce jour, on peut faire ce qu’on veut comme calculs aisément compréhensibles.

    Ce Lundi iso0 est bien pratique, j’incline volontiers à le baptiser isozéro de l’année.
    L’isozéro est le Lundi de la semaine iso0,
    de la même façon que ce que j’ai appelé iso-premier dans un post précédent est le Lundi de la semaine iso1 (c’est l’iso-Premier-de-l’An puisque les iso-années commencent toutes un Lundi).




    Bon, allez, voilà mon nouveau code peaufiné
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from datetime import date, timedelta
     
    def les_7jours_de(annne,sem):
        d0 = date(annne-1,12,22)
     
        while d0.weekday():  d0 += timedelta(1)
     
        d =  d0 + timedelta(weeks=sem)
     
        for j in xrange(7):  print d + timedelta(j)
    Il est moins abscons que mon précédent code à formule, et surtout plus facile à retrouver en peu de temps.

    Je trouve en effet qu’il n’est guère plus difficile de se rappeler que
    la semaine iso0 d’une iso-année commence au plus tôt le 22 Décembre de l’année précédente
    que de se rappeler que le 4 Janvier est toujours dans la semaine iso1.

    - D’une part le 22 Décembre est (annee,12,22) ,ce qui visuellement est assez mémorisable.

    - D’autre part le 22 Décembre est l’un des jours dans lesquels survient généralement le solstice d’hiver.

    <minute culturelle>
    Dans le calendrier grégorien, les dates de solstices varient suivant les années

    Le solstice de décembre a généralement lieu le 21 ou le 22 décembre. Il est tombé un 23 décembre en 1903 et il faudra attendre le début du XXIVe siècle pour le voir se produire de nouveau à cette date. Il est tombé un 20 décembre 10 fois à la fin du XVIIe siècle et tombera de nouveau à cette date à la fin du XXIe siècle et à la fin du XXVe siècle.


    http://fr.wikipedia.org/wiki/Solstice
    </minute culturelle>

    En fait, le solstice de décembre a lieu très généralement dans l’après-midi du 21 Décembre ou le matin du 22 Décembre.

    Le 22 Décembre est le 2iéme des 2 jours habituels du 12iéme mois pour le solstice de Décembre. Si avec tout ces 2, on ne se rappelle pas que la semaine iso0 commence au plus tôt le 22 Décembre, c’est qu’on ne pense qu’en 0 et 1 !!



    Si on tient à faire tout à la Zavonen, on écrira:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from datetime import date, timedelta
     
    def les_7jours_de(annne,sem):
        d0 = date(annne-1,12,22)
     
        while d0.weekday():  d0 += timedelta(1)
     
        d =  d0 + timedelta(-1, weeks=sem)
     
        for j in xrange(7):
            d += timedelta(1)
            print d

  12. #12
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 76
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Points : 1 913
    Points
    1 913
    Par défaut @eyquem
    Bon, rien à dire c'est parfait, je vais même dire 'définitif'.
    Une seule question...
    Où trouves-tu le temps de rédiger tout ça ???

  13. #13
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Comme toute passion dévorante, Python me permet de manger très vite et j’économise du temps sur les repas.
    De plus je rumine beaucoup les problèmes et les réponses en dehors de l’écran

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 13/10/2013, 22h47
  2. Réponses: 3
    Dernier message: 22/02/2012, 14h37
  3. Réponses: 1
    Dernier message: 06/11/2009, 13h52
  4. Réponses: 1
    Dernier message: 18/04/2008, 14h40
  5. Comment récupérer le numéro de la semaine ?
    Par claude dans le forum Langage
    Réponses: 7
    Dernier message: 25/06/2004, 15h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo