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

C# Discussion :

Trouver la date via numéro de semaine


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut Trouver la date via numéro de semaine
    Salut à toutes (et à tous),

    le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    System.Globalization.Calendar calendrier = CultureInfo.InvariantCulture.Calendar;
    int MaSuperSemaine = Calendrier.GetWeekOfYear(MaSuperDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    me permet de récupérer le numéro de semaine de MaSuperDate;
    c'est super comme fonction, mais il me faut la fonction inverse.
    j'aimerais maintenant retrouver les dates du lundi au dimanche de la semaine (au pif) 24 de cette année...

    quelqu'un saurait comment faire ? (sans regarder le calendrier bande de tricheurs !)

    allé, seul le lundi m'intéresse (avec des calculs super complexes je retrouverais les autres dates)

    Merci beau cou !

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Amusant.

    Quelque chose comme cela : (non testé, tappé à la volée)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     System.Globalization.Calendar calendar = new System.Globalization.GregorianCalendar();
    int searchedWeek = 10; // N° de semaien à rechercher
    DateTime dtFirstDayFirstWeek = DateTime.MinValue; // pour éviter erreur de compil
    for (int iWeek = 0,  iDay = 1; iWeek != 1; iDay++ )
    {
        dtFirstDayFirstWeek = new DateTime(DateTime.Now.Year, 1, iDay);
        iWeek = calendar.GetWeekOfYear(dtFirstDayFirstWeek, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
    }
    DateTime firstDayOfGivenWeek = calendar.AddWeeks(dtFirstDayFirstWeek, searchedWeek - 1);
    En gros, tu trouves la date du premier jour de la premiere semaine, et tu ajoute le numéro effectif de la semaine que tu cherches -1.

    EDIT : testé et fonctionne.
    EDIT2 : AddDays remplacé par AddWeeks suite à la correction publiée par SehnSucht.

  3. #3
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Bonjour,

    Exercice intéressant, bien que la solution de Bluedeep fonctionne, je donne tout de même ma solution, on sait jamais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //ne pas oublier le using System.Globalization;
    //weekNumber: n° de semaine recherché
    Calendar gregorian = new GregorianCalendar();
    DateTime firstDayYear = new DateTime(DateTime.Now.Year, 1, 1);
    int diff = (int)DayOfWeek.Monday - (int)firstDayYear.DayOfWeek;
    DateTime closestMonday = firstDayYear.AddDays(diff);
     
    return gregorian.AddWeeks(closestMonday, weekNumber);
    On récupère le premier jour de l'année, auquel on ajoute/retire l'écart entre le jour que ça tombe et le jour souhaité (ici un lundi) et on ajoute le nombre de semaines.

    Cordialement !

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Bonjour,

    Citation Envoyé par Sehnsucht Voir le message
    On récupère le premier jour de l'année, auquel on ajoute/retire l'écart entre le jour que ça tombe et le jour souhaité (ici un lundi) et on ajoute le nombre de semaines.

    Cordialement !
    Ta solution est indéniablement plus compacte que la mienne

    Néanmoins, elle souffre, sauf erreur de ma part, d'un défaut dans la détermination de la date de début de la première semaine.

    En effet, tu sembles considérer que la première semaine est celle qui contient le 1/1. Malheureusement d'une part (si on en juge par l'exemple posté par le PO), ce n'est pas l'option choisie par le PO, et de plus, dans ma solution j'ai voulu conserver l'aspect paramétrable de la détermination de la première semaine (via l'enum CalendarWeekRule).

    Exemple concret avec ton calcul: si le 1/1 tombe un dimanche, tu vas considérer que la première semaine démarre le 26/12, ce qui n'est pas correct.

    Sinon, bien vu le AddWeeks , je ne me rappelais tout simplement plus de l'existence de cette méthode (auquel cas mon code gagne à être modifié sur sa dernière instruction - le AddDays pouvant avantageusement être remplacé).

  5. #5
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Et pour finir, la solution avec une classe d'extension à Calendar, ce qui est quand même plus maniable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    using System.Globalization;
    public static class CalendarExtension
    {
        public static DateTime GetFirstDayDateOfFirstWeek(this Calendar calendar, 
                                                CalendarWeekRule weekRule, 
                                                DayOfWeek dayOfWeek,
                                                int year)
        {
            DateTime dtFirstDayFirstWeek = DateTime.MinValue;
            for (int iWeek = 0, iDay = 1; iWeek != 1; iDay++)
            {
                dtFirstDayFirstWeek = new DateTime(year, 1, iDay);
                iWeek = calendar.GetWeekOfYear(dtFirstDayFirstWeek, weekRule, dayOfWeek);
                DayOfWeek d;
            }
            return dtFirstDayFirstWeek;
        }
     
        public static DateTime GetFirstDayDateOfWeek(this Calendar calendar,
                                                CalendarWeekRule weekRule,
                                                DayOfWeek dayOfWeek,
                                                int iWeek,
                                                int year)
        {
            if (iWeek <= 0)
            {
                throw new ArgumentOutOfRangeException("Week ne peut pas être <= 0");
            }
            DateTime dtFirstDayFirstWeek = GetFirstDayDateOfFirstWeek(calendar, weekRule, dayOfWeek, year);
            return calendar.AddWeeks(dtFirstDayFirstWeek, iWeek - 1);
        }
    }
    Test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
               Calendar calendar = new GregorianCalendar();
            DateTime firstDayOfGivenWeek = calendar.GetFirstDayDateOfWeek(CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday, 10, 2011);

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    Merci pour votre aide à tous les deux,
    je me suis inspiré de vos solutions pour créer ma classe dont voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Globalization;
     
    namespace Outils
    {
        public class Outils_Dates
        {
            public static List<DateTime> Recup_Dates_Par_NumSemaine(int numSemaine, int Annee)
            {
                if ((numSemaine <= 0) || (numSemaine > 53))
                    throw new ArgumentOutOfRangeException("numSemaine",numSemaine ,"Numéro de semaine incorrect !");
     
                //-1 car on partira de la semaine 1 (et non de la semaine zéro ...)
                int ecartJoursSemaineDesiree = 7 * (numSemaine - 1);
                List<DateTime> mesDates = new List<DateTime>();
                Calendar monCalendrier = new GregorianCalendar();
                DateTime datePremierJourAnnee = new DateTime(Annee, 1, 1);
                DateTime datePremierJourPremiereSemaineAnnee = DateTime.MinValue;
                DateTime datePremierJourSemaineDesiree = DateTime.MinValue;
     
                //je vais tester les 6 jours autour du nouvel an
                //ben ouai, la règle étant que c'est la première semaine comptant au moins 4 jours dans la nouvelle année            
                //donc... le premier Lundi peut être à nouvel an +- 3 jours
                //donc entre le 29/12/annee-1 et le 4/1/annee inclus
                for (int cpt = -3; cpt<=3; cpt++)
                {
                    datePremierJourPremiereSemaineAnnee = datePremierJourAnnee.AddDays(cpt);
     
                    //je récupère le numéro de semaine de la date obtenue
                    int premiereSemaineAnnee = monCalendrier.GetWeekOfYear(datePremierJourPremiereSemaineAnnee, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
     
                    //si le numéro est <> 1 c'est encore l'année précédente
                    //si le numéro est 1 je sors de la boucle avec mon lundi :)
                    if (premiereSemaineAnnee == 1)
                        break;
                }
     
                //j'ajoute l'écart à ce premier lundi pour trouver MON lundi
                datePremierJourSemaineDesiree = datePremierJourPremiereSemaineAnnee.AddDays(ecartJoursSemaineDesiree);
     
                //ajout de dernière minute : si ce lundi est la premier semaine de l'année prochaine c'est pas bon !
                if ((datePremierJourSemaineDesiree.Year > Annee) && (monCalendrier.GetWeekOfYear(datePremierJourPremiereSemaineAnnee, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday) == 1))
                    throw new ArgumentOutOfRangeException("numSemaine", numSemaine, "Ce numéro de semaine n'existe pas pour cette année !");
     
                //puis j'ajoute les 7 jours de cette semaine à mon tableau
                for (int cpt = 0; cpt < 7; cpt++)
                    mesDates.Add(datePremierJourSemaineDesiree.AddDays(cpt));
     
                return mesDates;
            }
        }
    }
    - en effet, le premier lundi peut tout à fait être le 29 décembre de l'année précédente, ce qui pouvait poser problème.
    - la fonction AddWeeks n'existe pas dans VS2005 :/

  7. #7
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Bonjour,



    Ta solution est indéniablement plus compacte que la mienne

    Néanmoins, elle souffre, sauf erreur de ma part, d'un défaut dans la détermination de la date de début de la première semaine.

    En effet, tu sembles considérer que la première semaine est celle qui contient le 1/1. Malheureusement d'une part (si on en juge par l'exemple posté par le PO), ce n'est pas l'option choisie par le PO, et de plus, dans ma solution j'ai voulu conserver l'aspect paramétrable de la détermination de la première semaine (via l'enum CalendarWeekRule).

    Exemple concret avec ton calcul: si le 1/1 tombe un dimanche, tu vas considérer que la première semaine démarre le 26/12, ce qui n'est pas correct.

    Sinon, bien vu le AddWeeks , je ne me rappelais tout simplement plus de l'existence de cette méthode (auquel cas mon code gagne à être modifié sur sa dernière instruction - le AddDays pouvant avantageusement être remplacé).
    Je peux également faire erreur, mais il me semble que justement ça colle juste :
    Si le 1/1 est un dimanche alors (int)DayOfWeek.Monday - (int)firstDayYear.DayOfWeek vaudra 1 et donc firstDayYear.AddDays(diff) me reportera au 2/1 pas au 26/12.

    Quant aux autres cas où je me ramène au lundi de l'année précédente, c'est compensé dans mon utilisation de AddWeeks, tu l'utilises toujours avec un "offset" de -1 alors que je l'utilise sans changement.

    Après j'avoue ne pas avoir poussé les tests très loin, et que ça manquait clairement de modularité.

    @Themacleod1980 :
    Tu devrais vérifier pour la méthode AddWeeks, d'après sa documentation MSDN cette méthode semble exister depuis la toute première version du framework
    Version Information
    .NET Framework
    Supported in: 4, 3.5, 3.0, 2.0, 1.1, 1.0
    Cordialement !

  8. #8
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Sehnsucht Voir le message
    Je peux également faire erreur, mais il me semble que justement ça colle juste :
    Si le 1/1 est un dimanche alors (int)DayOfWeek.Monday - (int)firstDayYear.DayOfWeek vaudra 1
    Tu as raison sur cas précis, j'étais parti dans l'idée MonDay = 0 or c'est Sunday = 0.
    Donc ce cas est juste, MAIS j'en prends un autre.

    Si le 1/1 tombe un samedi (6), on a le début de la première semaine qui tombera le 01/01 - 5 jours, soit le 27/12.

    Mon exemple était mauvais (je n'avais pas été voir la définition de l'enum ), mais mon raisonnement est correct.

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

Discussions similaires

  1. [Crystal] transformation d'une date en numéro de semaine
    Par barna dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 24/03/2017, 09h41
  2. [XL-2007] Créer un graphique avec deux axes des abscisses liés (date et numéro de semaine)
    Par LawNasK dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 27/05/2015, 10h27
  3. [MySQL-5.5] Peut-on encoder des champs date en numéros de semaines?
    Par creation159 dans le forum Requêtes
    Réponses: 1
    Dernier message: 05/08/2013, 22h07
  4. [AC-2003] Convertir une date en numéro de semaine
    Par sniper2002 dans le forum Access
    Réponses: 16
    Dernier message: 25/07/2010, 20h52
  5. [MySQL] Date et numéro de semaine
    Par Devilju69 dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 02/06/2009, 14h23

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