Partage
  • Partager sur Facebook
  • Partager sur Twitter

zChance

19 Juin - 15 Juillet

    28 juin 2010 à 11:22:06

    Deux apparentes erreurs :
    1)

    Citation : Etienne-02


    int annee = heureLocale->tm_year + 1900;
    	for(annee = 2010 ; annee <=2010 ; annee++)
    



    Tu sembles croire que modifier annee va modifier heureLocale->tm_year + 1900.


    2)


    Citation : Etienne-02


    for(jourComplet = 0 ; jourComplet <= 6 ; jourComplet++)
    				{
    




    C'est pas ça qu'il faut faire, il faut juste lire la valeur de jourComplet et pas parcourir toutes les valeurs possibles.
    • Partager sur Facebook
    • Partager sur Twitter
      28 juin 2010 à 11:24:18

      Bon je connais pas time.h, et c'est la première fois que je participe, donc je pense que ça va pas être terrible...
      Voila ma solution
      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>
      
      time_t vendredi_13 ()
      {
          time_t next13 = time (NULL);
          next13 += 86400;
          struct tm date = *localtime (&next13);
          while (date.tm_wday != 5)
          {
              next13 += 86400;
              date = *localtime (&next13);
              while (date.tm_mday != 13)
              {
                  next13 += 86400;
                  date = *localtime (&next13);
              }
          }
          return next13;
      }
      
      int main ()
      {
          time_t vendredi = vendredi_13 ();
          struct tm date = *localtime (&vendredi);
          char const * const jours[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
          char const * const mois[] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
      
          printf ("Prochain vendredi 13 : ");
          printf ("%s %d %s %d\n", jours[date.tm_wday], date.tm_mday, mois[date.tm_mon], 1900+date.tm_year);
      
          printf ("Appuyez sur entree \n");
          getchar ();
          return EXIT_SUCCESS;
      }
      


      et voila la réponse :
      Prochain vendredi 13 : Vendredi 13 Aout 2010
      Appuyez sur entree


      Merci à vous pour ces idées d'exercices =)
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        28 juin 2010 à 11:41:05

        Citation : candide


        C'est pas ça qu'il faut faire, il faut juste lire la valeur de jourComplet et pas parcourir toutes les valeurs possibles.



        Mais la valeur de jourComplet ne se modifie que de jour en jour, non ? Donc si je ne fais que lire cette variable, j'aurais tout simplement le "jour d'aujourd'hui" ? :euh:
        • Partager sur Facebook
        • Partager sur Twitter
          28 juin 2010 à 13:02:30

          Citation : Etienne-02

          Citation : candide


          C'est pas ça qu'il faut faire, il faut juste lire la valeur de jourComplet et pas parcourir toutes les valeurs possibles.



          Mais la valeur de jourComplet ne se modifie que de jour en jour, non ? Donc si je ne fais que lire cette variable, j'aurais tout simplement le "jour d'aujourd'hui" ? :euh:



          Ton code est complètement à reprendre car tu ne sais déjà pas quel algorithme appliquer et je me demande même si tu sais exactement ce que tu cherches à faire.
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            28 juin 2010 à 13:05:18

            Je cherche à parcourir le calendrier 2010 et à afficher un Vendredi 13 dès que le programme en trouve un. Je fais un clean de mon projet alors et je vais réfléchir...
            • Partager sur Facebook
            • Partager sur Twitter
              28 juin 2010 à 13:36:15

              Citation : candide

              Citation : Marc Mongenet

              Oui mais la solution que je vois allonge le code de ma fonction d'environ 50%.


              Ce n'est pas une bonne solution que de donner un mauvais algorithme sous prétexte que ça rallonge le code.


              C'est toujours mieux que laisser passer un bogue en essayant d'optimiser. :-°
              Ton code oublie de calculer tm_wday avant de le tester.

              Cela dit, les fonctions de time.h et leurs spécifications me laissent perplexe.
              • Partager sur Facebook
              • Partager sur Twitter
                28 juin 2010 à 13:42:55

                @Chockosta:
                Ton utilisation de time n'est pas correcte.
                next13 += 86400;
                

                Rien n'indique que cette valeur soit exprimée en seconde(le <man>time traite de la fonction posix, aux spécifications différentes de la fonction time présente dans la norme)
                On ne travaille jamais directement sur le retour de time. Ce retour sert d'argument pour d'autre fonctions de <time.h>, c'est tout.

                @candide: toujours pas compris le problème avec mktime

                Citation : <man>mktime

                The original values of the tm_wday and tm_yday components of the struc-
                ture are ignored. The original values of the other components are not
                restricted to their normal ranges and will be normalized, if need be.
                For example, October 40 is changed into November 9...
                ...
                The asctime(), ctime(), difftime(), gmtime(), localtime(), and mktime()
                functions conform to ISO/IEC 9899:1990 (``ISO C90''), and conform to
                ISO/IEC 9945-1:1996 (``POSIX.1'')...


                • Partager sur Facebook
                • Partager sur Twitter
                Zeste de Savoir, le site qui en a dans le citron !
                  28 juin 2010 à 15:48:48

                  Arf et moi qui pensais avoir l'algo le plus naif du monde...

                  #include <stdio.h>
                  #include <time.h>
                  
                  typedef char const * const S_char;
                  typedef struct tm s_tm;
                  
                  S_char g_days[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
                  S_char g_months[] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout",
                                      "Septembre", "Octobre", "Novembre", "Decembre"};
                  
                  time_t      vendredi_13(void)
                  {
                      time_t  now;
                      s_tm    *tm_now;
                  
                      time(&now);
                      tm_now = localtime(&now);
                      while (tm_now->tm_mday != 13 || tm_now->tm_wday != 5)
                          {
                              ++tm_now->tm_mday;
                              mktime(tm_now);
                          }
                      return (mktime(tm_now));
                  }
                  
                  int         main(void)
                  {
                      time_t  vendredi;
                      s_tm    *date;
                  
                      vendredi = vendredi_13();
                      date = localtime(&vendredi);
                      printf("%s %d %s %d\n", g_days[date->tm_wday], date->tm_mday,
                             g_months[date->tm_mon], date->tm_year + 1900);
                      return (0);
                  }
                  


                  Je me referais a ca pour mktime,

                  http://www.cplusplus.com/reference/clibrary/ctime/mktime/

                  plus precisement a ca :

                  /* call mktime: timeinfo->tm_wday will be set */
                  
                  • Partager sur Facebook
                  • Partager sur Twitter
                    28 juin 2010 à 16:19:40

                    Citation : Marc Mongenet


                    C'est toujours mieux que laisser passer un bogue en essayant d'optimiser. :-°



                    autrement dit : un algorithme normal est l'optimisation d'un mauvais algorithme !! Fallait oser quand même.


                    Citation : Marc Mongenet


                    Ton code oublie de calculer tm_wday avant de le tester.


                    Un bug ? bof, en rééditant, j'ai oublié la ligne mktime(t) qui initialise .


                    Citation : GurneyH


                    @candide: toujours pas compris le problème avec mktime

                    Citation : <man>mktime

                    The original values of the tm_wday and tm_yday components of the struc-
                    ture are ignored. The original values of the other components are not
                    restricted to their normal ranges and will be normalized, if need be.
                    For example, October 40 is changed into November 9...
                    ...
                    The asctime(), ctime(), difftime(), gmtime(), localtime(), and mktime()
                    functions conform to ISO/IEC 9899:1990 (``ISO C90''), and conform to
                    ISO/IEC 9945-1:1996 (``POSIX.1'')...




                    Moi je me réfère pas à la Norme POSIX, je me réfère à la Norme du langage C 99. Où la Norme C99 explique-t-elle clairement que le 31 juin (qui est une date illégale) est le 1er juillet ou que le 13ème mois de l'année c'est le mois de janvier ? Où explique-t-elle c'est que le -8 où le -20 du mois ? Où la Norme explique-t-elle comment la fonction mktime modifie le champ tm_isdst ? Ainsi, dans le code que j'ai proposé et qui est directement inspiré de la Norme, si je ne prends pas le soin de mettre à -1 la valeur du champ tm_isdst, la fonction me retire 1 au nombre d'heures (heure d'hiver) si bien que je passe à un moment à des heures négatives et donc à une date fausse. Sais-tu pourquoi ?

                    Citation : Adroneus

                    Arf et moi qui pensais avoir l'algo le plus naif du monde...

                    ++tm_now->tm_mday;
                    


                    Mêmes problèmes que les codes déjà cités :
                    1) c'est quoi le 31 juin ?
                    2) inutile de parcourir les 365 jours si on a un calendrier sous les yeux et qu'on cherche les vendredis 13.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 juin 2010 à 16:30:30

                      Personne ne te parle du 31 juin, on te parle d'un "index" de jour qui ne correspond pas au bon et se fait donc reinitialiser correctement... c'tout, si mktime sert aussi a ca, pourquoi s'en priver? La fonction detecte une erreur et la corrige...
                      • Partager sur Facebook
                      • Partager sur Twitter
                        28 juin 2010 à 16:37:31

                        Tu retrouves la passage du <man> dans la norme.

                        Pour le comportement avec le champs tm_isdate initialisé à 0, ça montre surtout que c'est probablement une mauvaise idée d'initialiser les champs de la structure à la main , alors que localetime le fait très bien.
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Zeste de Savoir, le site qui en a dans le citron !
                          28 juin 2010 à 17:05:33

                          mon code :
                          time_t vendredi_13(void)
                          {
                              struct tm *tempsActuel;
                              time_t temps = time(NULL);
                              tempsActuel = localtime(&temps);
                          
                              while(tempsActuel->tm_wday != 5)
                              {
                                  temps += 60*60*24;
                                  tempsActuel = localtime(&temps);
                              }
                              while(tempsActuel->tm_mday != 13)
                              {
                                  temps += 60*60*24*7;
                                  tempsActuel = localtime(&temps);
                              }
                              return temps;
                          }
                          


                          il est plutot (beaucoup?) simple, mais comme certains vont surement me le dire, je fais des tours de boucle en trop : je regarde a chaque vendredi si c'est un vendredi 13 plutot qu'à chaque 13 si c'est un vendredi. Mais avec ma méthode je ne vois pas comment faire autrement.
                          • Partager sur Facebook
                          • Partager sur Twitter
                            28 juin 2010 à 17:40:43

                            Citation : alex922

                            mon code :

                            time_t vendredi_13(void)
                            {
                                struct tm *tempsActuel;
                                time_t temps = time(NULL);
                                tempsActuel = localtime(&temps);
                            
                                while(tempsActuel->tm_wday != 5)
                                {
                                    temps += 60*60*24;
                                    tempsActuel = localtime(&temps);
                                }
                                while(tempsActuel->tm_mday != 13)
                                {
                                    temps += 60*60*24*7;
                                    tempsActuel = localtime(&temps);
                                }
                                return temps;
                            }
                            



                            il est plutot (beaucoup?) simple, mais comme certains vont surement me le dire, je fais des tours de boucle en trop : je regarde a chaque vendredi si c'est un vendredi 13 plutot qu'à chaque 13 si c'est un vendredi. Mais avec ma méthode je ne vois pas comment faire autrement.


                            Tu vas te faire taper sur les doigts à propos du time_t :p
                            Je poste un autre code moins naïf que celui posté précédemment qui n'utilise pas mktime (comme ça je suis sûr de pas me faire taper sur les doigts :D ) et qui ne testes que les 13 de chaque mois :
                            #include <stdio.h>
                            #include <stdlib.h>
                            #include <time.h>
                            
                            int bissextile(int y)
                            {
                                return ((y%4 == 0) && (y%100 != 0 || y%400 == 0));
                            }
                            
                            void mise_a_jour(int *d, int *m, int *y, int *j)
                            {
                                int jours_mois[] = {31,(bissextile(*y) ? 29 : 28),31,30,31,30,31,31,30,31,30,31};
                                int tmp;
                            
                                if (*d < 13)
                                    while (*d != 13)
                                    {
                                        (*j) ++;
                                        (*d) ++;
                                    }
                                else if (*d > 13)
                                    while (*d != 13)
                                    {
                                        (*d) ++;
                                        (*j) ++;
                                        tmp = (*m);
                                        (*m) += (*d-1)/jours_mois[(*m)];
                                        (*d) = (*d-1)%jours_mois[tmp] + 1;
                                        (*y) += (*m)/12;
                                        (*m) %= 12;
                                    }
                            
                                (*j) %= 7;
                            }
                            
                            void vendredi(int j, int m, int y, int d, int last_year)
                            {
                                int jours_mois[] = {31,28,31,30,31,30,31,31,30,31,30,31};
                                mise_a_jour(&d,&m,&y,&j);
                            
                                while (y <= last_year)
                                {
                                    jours_mois[1] = bissextile(y) ? 29 : 28;
                            
                                    if (j == 5)
                                        printf("Vendredi 13/%d/%d\n",m+1,y);
                            
                                    j = (j+jours_mois[m])%7;
                                    m ++;
                                    y += m/12;
                                    m %= 12;
                                }
                            }
                            
                            int main()
                            {
                                const time_t tmp = time(NULL);
                                struct tm *t = gmtime(&tmp);
                                vendredi(t->tm_wday,t->tm_mon,t->tm_year+1900,t->tm_mday,2100);
                                return 0;
                            }
                            

                            Le code est assez long, j'utilise les fonctions de time pour obtenir la date actuel, je cherches ensuite le prochain 13 dans le mois (fonction mise_a_jour), c'est assez brute comme méthode mais bon.
                            • Partager sur Facebook
                            • Partager sur Twitter
                            Anonyme
                              28 juin 2010 à 17:45:19

                              Voici ma solution qui va vérifier chaque 13 du mois. C'est peut-être un peu le fouillis aussi je demande conseils à tous, qui êtes bien plus expérimentés que moi.

                              #include <stdio.h>
                              #include <time.h>
                              
                              int main (int argc, const char * argv[]) 
                              {
                              
                              	time_t timestampActuel;
                              	
                              	struct tm  *heureLocale;
                              	
                              	timestampActuel = time(NULL);
                              	
                              	heureLocale = localtime(&timestampActuel);
                              	
                              	int jourComplet = heureLocale->tm_wday;
                              	int mois = heureLocale->tm_mon;
                              	int annee = heureLocale->tm_year + 1900;
                              	
                              	
                              	char const * const TableauMois[12] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
                              	
                              	for(mois = 0 ; mois <= 11 ; mois++)
                              	{
                              		
                              		heureLocale->tm_mday = 13;
                              		heureLocale->tm_mon = mois;
                              
                              		timestampActuel = mktime(heureLocale);
                              		
                              		jourComplet = heureLocale->tm_wday; 
                              		
                              		if(jourComplet == 5)
                              		{
                              		printf("Vendredi 13 %s %d\n", TableauMois[mois], annee);
                                              }
                              	}
                                  return 0;
                              }
                              


                              Merci. :D
                              • Partager sur Facebook
                              • Partager sur Twitter
                                28 juin 2010 à 17:58:34

                                quel est le problème avec mktime() ?
                                apparement ça ne renvoie pas toujours le nombre en secondes écoulées depuis l' "Epoch" (j'ai appris ce mot aujourd'hui alors je l'utilise :p ) ?!

                                en tout cas bon exercice, au debut il fait peur, faut faire un peu de recherche dans la man
                                (surtout pour comprendre comment marchait time(), localtime() et asctime() parce que dans la man il donne un exemple où ils utilisent les trois à la fois, impossible de savoir ce que renvoie chacune!)

                                mais au final on en sort en connaissant un peu time.h, que je n'utilisais avant que pour initialiser srand :)
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  28 juin 2010 à 18:09:50

                                  Citation : Adroneus

                                  Personne ne te parle du 31 juin



                                  Bien sûr que si, regarde un peu ce que fait TON code, en incrémentant tm_now->tm_mday, tu déclares assez vite un 31 juin : c'est défini où un 31 juin ? Des 29 février ça existe tous les 4 ans mais un 31 juin ça n'existe jamais donc il faut bien que ce genre de date imaginaire soit mis en correspondance avec une date valide par une règle explicite.

                                  Citation : GurneyH

                                  Tu retrouves la passage du <man> dans la norme.



                                  Ben autant citer Dieu que ses saints ;)

                                  Sinon ça ne répond à la question que je pose.

                                  Par ailleurs, ta Norme Posix donne un exemple qui n'est absolument pas une conséquence de ce que dit la règle générale qui je le répète encore, est extrêmemnt imprécise.



                                  Citation : GurneyH


                                  Pour le comportement avec le champs tm_isdate initialisé à 0,



                                  tm_isdate ? c'est quoi ? tu veux parler de tm_isdst initialisé non pas à 0 mais à -1 ?

                                  Citation : GurneyH


                                  ça montre surtout que c'est probablement une mauvaise idée d'initialiser les champs de la structure à la main, .


                                  Au passage, initialiser à la main c'est déjà mieux que ne pas initialiser du tout, à l'instar de ton code ...

                                  Citation : GurneyH


                                  alors que localetime le fait très bien.


                                  Bof, ça encore ce n'est pas si clair. Où dois-je comprendre dans la Norme que mktime a besoin que localtime refasse le travail derrière pour avoir une date correcte. Certes c'est ce que dit Plauger, cf. ma citation dans un message précédent mais, je m'en moqie de ce que dis un tel ou un tel, ce que je veux savoir c'est où le document de référence me le dit. D'ailleurs, dans l'exemple qu'elle donne, la Norme n'utilise pas localtime pour initialiser la date struct tm. Et puis, où est documentée la façon d'initialiser localtime ? Par exemple, dans le code d'Adroneus, elle place le champ tm_isdst à 1 et non pas à -1.



                                  Citation : Etienne-02

                                  Voici ma solution qui va vérifier chaque 13 du mois. C'est peut-être un peu le fouillis



                                  Excuse-moi, je n'ai pas le temps de regarder ton code.

                                  Néanmoins, en le regardant, je me dis que le problème tel que l'auteur l'a posé empêche toute vérification sérieuse puisqu'on ne peut vérifier que le 13 août 2010. À partir du 14 août 2010 on pourra vérifier le 13 mai 2011 ... Donc, si vous voulez écrire un code vérifiable, écrivez plutôt un code qui donne le prochain vendredi 13 à partir d'une date donnée (et pas à partir du moment où j'exécute le code ce qui est beaucoup plus limité).
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    28 juin 2010 à 18:33:23

                                    Citation : candide


                                    au passage, initialiser à la main c'est déjà mieux que ne pas initialiser du tout, à l'instar de ton code ...


                                    o_O
                                    struct tm *date = localtime(&current);
                                    

                                    c'est pas une initialisation, ça?

                                    et oui, pas tm_isdate :honte:
                                    en plus j'avais les différents champs sous les yeux au moment d'écrire ce truc.

                                    Pour ta question sur le champs tm_isdst, je n'en sais rien du tout...
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Zeste de Savoir, le site qui en a dans le citron !
                                      28 juin 2010 à 23:11:42

                                      @candide

                                      Citation : ISO/IEC 9899:201x

                                      7.25.2.3 The mktime function
                                      Synopsis

                                      #include <time.h>
                                      time_t mktime(struct tm *timeptr);
                                      



                                      Description

                                      The mktime function converts the broken-down time, expressed as local time, in the
                                      structure pointed to by timeptr into a calendar time value with the same encoding as
                                      that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above.
                                      298)
                                      On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time, but with their values forced to the ranges indicated above; the final value of tm_mday is not set until tm_mon and tm_year are determined.


                                      Je vois pas ce qu'il te faut de plus...
                                      voici les range en question :

                                      Citation : ISO/IEC 9899:201x

                                      The range and precision of times representable in clock_t and time_t are
                                      implementation-defined. The tm structure shall contain at least the following members,
                                      in any order. The semantics of the members and their normal ranges are expressed in the
                                      comments.
                                      296)

                                      int tm_sec; // seconds after the minute — [0, 60]
                                      int tm_min; // minutes after the hour — [0, 59]
                                      int tm_hour; // hours since midnight — [0, 23]
                                      int tm_mday; // day of the month — [1, 31]
                                      int tm_mon; // months since January — [0, 11]
                                      int tm_year; // years since 1900
                                      int tm_wday; // days since Sunday — [0, 6]
                                      int tm_yday; // days since January 1 — [0, 365]
                                      int tm_isdst; // Daylight Saving Time flag
                                      

                                      Voila, moi j'en conclus que ce que l'on fait est legal et prevu par la norme...
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        28 juin 2010 à 23:28:22

                                        En fait c'est la partie qui dit "are set appropriately" qui n'est pas du tout précise... En gros 31 juin => 1er juillet (on a dépassé le nombre de jours donc on passe au mois suivant), ou 31 juin => 1er juin (date impossible, donc on reprend le mois). C'est juste une question de précision de la norme en fait.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          28 juin 2010 à 23:38:16

                                          La norme est très imprécise, sur ce point; c'est vrai, et sur d'autres!

                                          C'est typique!
                                          Pas plus de certitudes que toi, Holt!
                                          Mais, la question reste intéressante!

                                          Sinon, le C, c'est facile^^



                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Zeste de Savoir, le site qui en a dans le citron !
                                            29 juin 2010 à 0:53:42

                                            Citation : GurneyH

                                            Citation : candide


                                            au passage, initialiser à la main c'est déjà mieux que ne pas initialiser du tout, à l'instar de ton code ...


                                            o_O

                                            struct tm *date = localtime(&current);
                                            


                                            c'est pas une initialisation, ça?



                                            Oui mais visiblement ça ne semble par suffire. Ton code donne :

                                            Citation : GurneyH

                                            struct tm* vendredi13(struct tm *t)
                                            {
                                                do
                                                {
                                                    t->tm_mday++;
                                                    mktime(t);
                                                }while(t->tm_wday != 5 || t->tm_mday != 13);
                                            
                                                return t;
                                            }
                                            


                                            Tu appelles mktime() après avoir changé un champ mais tu n'initialises pas à la main, en particulier tu n'initialises pas le champ tm_isdst (tu fais confiance à mktime). Mais ça peut donner des résultats inattendus, par exemple ce code

                                            #include <stdio.h>
                                            #include <time.h>
                                            
                                            void v13(struct tm *t)
                                            {
                                              if (t->tm_mday > 13)
                                                t->tm_mon++;
                                              t->tm_mday = 13;
                                              mktime(t);// omission signalée par Marc Mongenet
                                            
                                              while (t->tm_wday != 5)
                                                {
                                                  t->tm_mon++;
                                                  //t->tm_isdst = -1;
                                                  mktime(t);
                                                }
                                            }
                                            
                                            void ma_date(int j, int m, int a, struct tm *t)
                                            {
                                              t->tm_year = a - 1900;
                                              t->tm_mon = m - 1;
                                              t->tm_mday = j;
                                              t->tm_hour = 0;
                                              t->tm_min = 0;
                                              t->tm_sec = 1;
                                              t->tm_isdst = -1;
                                            }
                                            
                                            int main(void)
                                            {
                                              struct tm t;
                                            
                                              ma_date(15, 3, 2020, &t);
                                              v13(&t);
                                              printf("vendredi %d/%d/%d\n", t.tm_mday, 1 + t.tm_mon, 1900 + t.tm_year);
                                              return 0;
                                            }
                                            


                                            vendredi 12/2/2021





                                            où je demande un vendredi 13 et il me sort un vendredi 12 parce qu'à cause de l'heure d'été, mktime a reculé d'une heure à chaque appel le nombre d'heures d'une unité si bien que je finis par perdre un jour (12 au lieu de 13).



                                            Citation : Adroneus

                                            @candide

                                            Citation : ISO/IEC 9899:201x

                                            7.25.2.3 The mktime function




                                            Inutile de me citer tout ça in extenso, tu penses bien que ce passage je l'ai déjà lu et relu des dizaines de fois.


                                            Citation : Adroneus

                                            @
                                            Voila, moi j'en conclus que ce que l'on fait est legal et prevu par la norme...



                                            Ah oui, où la Norme dit-elle comment interpréter un 31 juin ? Dis moi où la Norme explique en fonction de quoi elle change l'indicateur d'heure d'été ce qui peut conduire à des erreurs de calculs de dates, cf. mon code ci-dessus. La Norme ne dit que des choses imprécises. Par exemple, que veut dire On successful completion ("completion" de quoi ?), que veut-dire " are set appropriately" (approprié en fonction de quoi, à partir de quelle règle explicite ???). Dans quel ordre les champs sont remplis ? A-t-on le droit d'avoir des mois ou des jours négatifs (pourquoi pas ?) ? etc.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              29 juin 2010 à 1:40:49

                                              Citation : candide

                                              par exemple ce code


                                              Quittes à le reprendre, il serait quand même bon de corriger le gros bogue avec tm_wday qui est testé sans être initialisé. Sans cela des débutant risqueraient d'être induit en erreur.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                29 juin 2010 à 1:55:07

                                                Citation : Marc Mongenet

                                                Citation : candide

                                                par exemple ce code


                                                Quittes à le reprendre, il serait quand même bon de corriger le gros bogue avec tm_wday qui est testé sans être initialisé. Sans cela des débutant risqueraient d'être induit en erreur.



                                                Oui, en effet, c'est le même oubli que ci-dessus, je rectifie. Mais ça ne change rien, le résultat reste aussi faux. Par contre, si je décommente t->tm_isdst = -1;, le résultat devient correct.
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  29 juin 2010 à 16:52:32

                                                  Bonjour.
                                                  J'ai décidé de participer ce moi ci :
                                                  #include <stdio.h>
                                                  #include <stdlib.h>
                                                  #include <time.h>
                                                  
                                                  int nb_j_mois[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
                                                  int nb_j_annee = 365;
                                                  
                                                  int bissextile(int annee)
                                                  {
                                                      return ((annee % 4 == 0 && annee % 100 != 0) || (annee % 400 == 0));
                                                  }
                                                  
                                                  void verif_date(struct tm *temps_h)
                                                  {
                                                      if(temps_h->tm_wday>6)
                                                      {
                                                          temps_h->tm_wday=5;
                                                      }
                                                      if(temps_h->tm_mday>nb_j_mois[temps_h->tm_mon])
                                                      {
                                                          temps_h->tm_mday-=nb_j_mois[temps_h->tm_mon];
                                                          temps_h->tm_mon++;
                                                      }
                                                      if(temps_h->tm_yday>nb_j_annee)
                                                      {
                                                          temps_h->tm_mon=0;
                                                          temps_h->tm_yday-=nb_j_annee;
                                                          temps_h->tm_year++;
                                                          if(bissextile(1900+temps_h->tm_year))
                                                          {
                                                              nb_j_mois[1]=29;
                                                              nb_j_annee=366;
                                                          }
                                                          else
                                                          {
                                                              nb_j_mois[1]=28;
                                                              nb_j_annee=365;
                                                          }
                                                      }
                                                  }
                                                  
                                                  struct tm vendredi_13 (struct tm temps_h) {
                                                      int x = 0;
                                                      if(bissextile(1900+temps_h.tm_year))
                                                      {
                                                          nb_j_mois[1]=29;
                                                          nb_j_annee=366;
                                                      }
                                                      if(temps_h.tm_wday<5)
                                                      {
                                                          x = 5-temps_h.tm_wday;
                                                      }
                                                      else
                                                      {
                                                          x = 12-temps_h.tm_wday;
                                                      }
                                                      temps_h.tm_wday=5;
                                                      temps_h.tm_mday+=x;
                                                      temps_h.tm_yday+=x;
                                                      verif_date(&temps_h);
                                                      while(temps_h.tm_wday != 5 || temps_h.tm_mday != 13)
                                                      {
                                                          temps_h.tm_wday+=7;
                                                          temps_h.tm_mday+=7;
                                                          temps_h.tm_yday+=7;
                                                          verif_date(&temps_h);
                                                      }
                                                  
                                                      return temps_h;
                                                  }
                                                  
                                                  int main (void) {
                                                      time_t temps = time(NULL);
                                                      struct tm temps_h = *localtime(&temps);
                                                      char const * const jours[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
                                                      char const * const mois[] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
                                                      int i=0, nb_v=10;
                                                  
                                                      printf("Combien de prochains vendredis 13 voulez-vous visualiser? ");
                                                      scanf("%d",&nb_v);
                                                      for(i=0;i<nb_v;i++)
                                                      {
                                                          temps_h=vendredi_13(temps_h);
                                                          printf("%s %d %s %d\n", jours[temps_h.tm_wday], temps_h.tm_mday, mois[temps_h.tm_mon], 1900+temps_h.tm_year);
                                                      }
                                                  
                                                      return EXIT_SUCCESS;
                                                  }
                                                  



                                                  Edit : Version commenté :
                                                  #include <stdio.h>
                                                  #include <stdlib.h>
                                                  #include <time.h>
                                                  
                                                  int nb_j_mois[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
                                                  int nb_j_annee = 365;
                                                  
                                                  int bissextile(int annee)
                                                  {
                                                      return ((annee % 4 == 0 && annee % 100 != 0) || (annee % 400 == 0));
                                                  }
                                                  
                                                  //Vérifie si la date est valide (exemple : si on est au 32 janvier le jour passe à 1 et le mois passe à février)
                                                  void verif_date(struct tm *temps_h)
                                                  {
                                                      if(temps_h->tm_wday>6)
                                                      {
                                                          temps_h->tm_wday=5;
                                                      }
                                                      if(temps_h->tm_mday>nb_j_mois[temps_h->tm_mon])
                                                      {
                                                          temps_h->tm_mday-=nb_j_mois[temps_h->tm_mon];
                                                          temps_h->tm_mon++;
                                                      }
                                                      if(temps_h->tm_yday>nb_j_annee)
                                                      {
                                                          temps_h->tm_mon=0;
                                                          temps_h->tm_yday-=nb_j_annee;
                                                          temps_h->tm_year++;
                                                          if(bissextile(1900+temps_h->tm_year))
                                                          {
                                                              nb_j_mois[1]=29;
                                                              nb_j_annee=366;
                                                          }
                                                          else
                                                          {
                                                              nb_j_mois[1]=28;
                                                              nb_j_annee=365;
                                                          }
                                                      }
                                                  }
                                                  
                                                  //fonction qui cherche le prochain vendredi.
                                                  //La fonction demande la date de départ et renvoie le prochain vendredi 13
                                                  struct tm vendredi_13 (struct tm temps_h) {
                                                      int x = 0;
                                                      if(bissextile(1900+temps_h.tm_year))// 1, on vérifie si l'année est bissextile.
                                                      {
                                                          nb_j_mois[1]=29; //si oui, il y à 29 jours en février
                                                          nb_j_annee=366;  //et 366 jours dans l'année.
                                                      }
                                                      // 2, on se "positionne" sur le prochain vendredi.
                                                      if(temps_h.tm_wday<5)//Si on est lundi, mardi, mercredi ou jeudi on récupère le nombre de jours restant avant le vendredi de cette semaine.
                                                      {
                                                          x = 5-temps_h.tm_wday;//vendredi=5 donc si on est lundi (1) il reste 5-1=4 jours avant vendredi.
                                                      }
                                                      else//sinon, on se "positionne" sur le vendredi de la semaine prochaine.
                                                      {
                                                          x = 12-temps_h.tm_wday;//7+5=12 (7 est la semaine entière et 5 est vendredi) exemples :
                                                                                 //si on est vendredi on cherche à se positionner sur le vendredi de la semaine prochaine donc on à 12-5=7 : dans 7 jours c'est le prochain vendredi.
                                                                                 //si on est samedi on a : samedi = 6 et 12-6=6 donc il reste 6 jours avant vendredi prochain.
                                                      }
                                                      temps_h.tm_wday=5;//on définit que le jours de la semaine est vendredi
                                                      temps_h.tm_mday+=x;//on se "positionne enfin
                                                      temps_h.tm_yday+=x;
                                                      verif_date(&temps_h);//on vérifie si la date est juste
                                                  
                                                      while(temps_h.tm_wday != 5 || temps_h.tm_mday != 13)
                                                      {
                                                          temps_h.tm_mday+=7;//on vas au vendredi suivant.
                                                          temps_h.tm_yday+=7;//idem avec ce compteur.
                                                          verif_date(&temps_h);//on vérifie la date.
                                                      }//Si c'est bien un vendredi 13 on sort de la boucle.
                                                  
                                                      return temps_h;//et on retourne le resutlat.
                                                  }
                                                  
                                                  int main (void) {
                                                      time_t temps = time(NULL);//On prend la date d'aujourd'hui.
                                                      struct tm temps_h = *localtime(&temps);//et on la convertit.
                                                      char const * const jours[] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
                                                      char const * const mois[] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
                                                      int i=0, nb_v=10;
                                                  
                                                      printf("Combien de prochains vendredis 13 voulez-vous visualiser? ");
                                                      scanf("%d",&nb_v);
                                                      for(i=0;i<nb_v;i++)
                                                      {
                                                          temps_h=vendredi_13(temps_h);//on réutilise à chaque fois la date du dernier vendredi 13 sauf au début où c'est la date d'aujourd'hui.
                                                          printf("%s %d %s %d\n", jours[temps_h.tm_wday], temps_h.tm_mday, mois[temps_h.tm_mon], 1900+temps_h.tm_year);//on affiche
                                                      }
                                                  
                                                      return EXIT_SUCCESS;
                                                  }
                                                  


                                                  Commentez mon code pour que je m'améliore s'il vous plait.
                                                  Merci d'avance.

                                                  Emmflo

                                                  PS : Désolé pour les variables globales. (en fais je considère que c'est des constantes qui nécessitent en cas particuliers d'être modifier donc je les ai déclaré un peu comme une constante)
                                                  PS2 : Je viens de remarquer qu'au début ça marche et que plus on regarde de vendredis plus le logiciel en manque. Si quelqu'un pouvais m'aider je lui en serais reconnaissant. Problème réglé, je réinitialisais mal les années.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                    29 juin 2010 à 20:10:07

                                                    Citation : Emmflo


                                                    Commentez mon code pour que je m'améliore s'il vous plait.



                                                    Déjà quand on parcourt ton code, on ne sait pas quelle est ta méthode, quel rôle laisses-tu aux foncions de time.h et quel calcul tu décides de faire toi-même. Tu devrais mettre un petit commentaire avant chaque fonction qu'on sache ce qu'elle fait.

                                                    Quand je vois des constantes magiques au beau milieu du code telles que 29, 366 ou 12, je me dis que c'est assez inorganisé.

                                                    Des machins comme

                                                    if(temps_h.tm_wday<5)
                                                        {
                                                            x = 5-temps_h.tm_wday;
                                                        }
                                                        else
                                                        {
                                                            x = 12-temps_h.tm_wday;
                                                        }
                                                    


                                                    me semblent tout ce qu'il y a de plus mystérieux.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Anonyme
                                                      1 juillet 2010 à 18:51:26

                                                      Voici mon code, ébauche des améliorations proposées par candide :

                                                      #include <stdio.h>
                                                      #include <time.h>
                                                      
                                                      int main (int argc, const char * argv[]) 
                                                      {
                                                      
                                                      	time_t timestampActuel;
                                                      	
                                                      	struct tm  *heureLocale;
                                                      	
                                                      	int anneeFin = 0;
                                                      	int moisFin = 0;
                                                      	
                                                      	timestampActuel = time(NULL);
                                                      	
                                                      	heureLocale = localtime(&timestampActuel);
                                                      	
                                                      	int jourComplet = heureLocale->tm_wday;
                                                      	int mois = heureLocale->tm_mon;
                                                      	int annee = heureLocale->tm_year + 1900;
                                                      	
                                                      	printf("Annee de fin de recherche\n");
                                                      	scanf("%d", &anneeFin);
                                                      	printf("Mois de fin de recherche\n");
                                                      	scanf("%d", &moisFin);
                                                      	
                                                      	char const * const TableauMois[12] = {"Janvier", "Fevrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"};
                                                      	
                                                      	for(annee = 2010 ; annee <= anneeFin ; annee++)
                                                      	{
                                                      		for(mois = 0 ; mois <= moisFin ; mois++)
                                                      		{
                                                      			
                                                      		heureLocale->tm_mday = 13;
                                                      		heureLocale->tm_mon = mois;
                                                      		heureLocale->tm_year = annee - 1900;
                                                      
                                                      		timestampActuel = mktime(heureLocale);
                                                      		
                                                      		jourComplet = heureLocale->tm_wday; 
                                                      		
                                                      		if(jourComplet == 5)
                                                      		{
                                                      		printf("\n\nVendredi 13 %s %d\n", TableauMois[mois], annee);
                                                                      }
                                                      		}
                                                      	}
                                                          return 0;
                                                      }
                                                      


                                                      Il recherche tous les Vendredi 13 à partir du jour où le code est exécuté et une date indiquée. Bon, c'est primitif : pas de vérification ni rien, c'est juste pour l'exercice. Pas taper candide pour les scanf() >_<

                                                      Par contre, j'ai un problème : quand je tape "2011" pour année fin et "02" pour mois fin, le programme ne me renvoie rien. Logiquement, il devrait m'afficher "Vendredi 13 Août 2010". Pourquoi ?

                                                      Bref, c'est mon premier exo avec vous, ça m'a beaucoup plu et j'attends avec impatience la série de Juillet !
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        1 juillet 2010 à 18:58:41

                                                        tut tut tu n'as pas le droit de faire comme ça :p
                                                        tu dois créer une fonction qui renvoie un time_t (bon ça change quasi rien, je suis d'accord !)

                                                        PS : tu ouvres un if dans ta boucle for et tu le fermes apres la boucle for ...
                                                        --> j'ai mal regardé
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Anonyme
                                                          1 juillet 2010 à 19:01:15

                                                          C'était un petit problème d'indentation. Sinon, tout était bien ouvert et fermé comme il le faut...
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            1 juillet 2010 à 19:01:52

                                                            oui oui désolé je m'en suis rendu compte j'ai édité
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              1 juillet 2010 à 19:25:43

                                                              Bonsoir.
                                                              Je voudrais avoir quelques commentaires sur mon code. Je demande ça car j'ai l'impression que personne n'as remarqué que j'ai édité mon message en rajoutant une version commenté de mon code (peut-être un peu trop d'ailleurs...)
                                                              Merci d'avance.
                                                              Emmflo
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              zChance

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown