Perfectionnement d'un calendrier perpetuel en C - C - Programmation
Marsh Posté le 01-04-2007 à 22:56:35
teycir a écrit : Bonjour;
|
Bon, je vais faire des remarques générales :
1) je crois qu'il y a trop de commentaires dans ton code
2) pourquoi utiliser 2 tableaux de mois "bissextile" et "n_bissextile" alors qu'ils sont identiques (à l'exception du 2° mois qui peut se gérer par un test)
3) essaye de penser au ternaire "? :" qui peut t'économiser parfois des lignes pour un résultat identique
Ex: Remplacer
if ( ans%4==0 && ans%100!=0 || ans%400==0 ) |
jrs = ((ans%4==0 && ans%100!=0 || ans%400==0) ?366 :365) - nb_jr (ms, ans); |
4) Tu peux optimiser ton test "bissextile". En effet, tel que tu l'as écris, tu fais à chaque test deux comparaisons "X ou Y" donc sur 1000 ans tu fais 2000 tests.
Si tu l'écris ainsi: "ans%4==0 && (ans%100!=0 || ans%400==0)" dès que l'année ne sera pas divisible par 4, l'évaluateur booléen arrêtera son évaluation donc sur 1000 ans tu ne feras que 1250 tests
5) Tu devrais mettre ton test "bissextile" en macro plus facile à intégrer dans le code. Et réfléchir aussi à l'inverser complètement car une année est plus souvent "non bissextile" que bissextile
6) t'as pensé aux 10 jours qui ont été enlevés au XVII° siècle par le pape Grégoire afin que notre calendrier rattrappe le soleil ?
Voilà - Pas évident comme algo...
Marsh Posté le 02-04-2007 à 14:10:31
Merci sve@r;
Effectivement; les jours à éliminer sont:
1- les 29 févriers des années non bissextiles
2- l'année 0
3- le 4, 5, 6, 6, 8, 9, 10, 11, 12, 13, 14, 15 octobre 1582 : le décalage grégorien qui supprima dix jours du calendrier, entre le 4 octobre 1582 et le 15 octobre 1582 pour les pays ayant immédiatement suivi Rome, ce qui permit de fixer de nouveau l%u2019équinoxe de printemps le 21 mars, comme ce fut le cas au début de l%u2019ère chrétienne
Les cas 2 et 3 semblent relativement faciles à supprimer, il suffit de rajouter des conditions à la ligne 80 du code : if ((ans >= -2000) && (ans <=4000) && (ms >=1) && (ms<=12) && (jr >=1) && (jr <= 31)).
Par contre les 29 févriers sont plus compliqués à supprimer.
J'ai pensé à tranformer les 3 conditions en booléens puis les insérer dans le if de la ligne 80 du code. Par ex mettre en place la fonction calcul année non bissextile + jour 29 + mois 2 en true (1), me semble être une solution pour le cas 1. Qu'en pensez-vous? Est-ce faisable?
A+
Marsh Posté le 02-04-2007 à 15:28:19
teycir a écrit : Merci sve@r; |
Moi, je commencerais par créer une structure spéciale pour gérer la date (un truc contenant jj/mm/aa). Comme ça, si on doit transmettre la date à une fonction, on lui passe un pointeur sur la structure et la fonction reçoit d'un coup le jj/mm/aa. Après-tout, ça sert à ça les structures.
Ensuite, je mettrais en place une fonction spéciale qui teste si la date rentrée est valide et qui renvoie V/F comme ça, l'algo de saisie est beaucoup plus simple à gérer. Ca pourrait être par exemple un truc comme ça
while (1) { |
Ensuite, la fonction qui gère la date pourra être programmée comme on veut, avec tous les algo imaginables et surtout évolutifs facilement. Si un jour t'as envie de passer de -6000 à +8000, la modif se fera dans la fonction en une seule fois.
Autre truc: Intéresse-toi aux structures "struct_tm" et aux fonctions associées => http://bat710.univ-lyon1.fr/~jcieh [...] ime.3.html. Il peut y avoir des trucs utiles dedans...
Marsh Posté le 02-04-2007 à 15:46:15
Sve@r a écrit : Moi, je commencerais par créer une structure spéciale pour gérer la date (un truc contenant jj/mm/aa). Comme ça, si on doit transmettre la date à une fonction, on lui passe un pointeur sur la structure et la fonction reçoit d'un coup le jj/mm/aa. Après-tout, ça sert à ça les structures.
|
Oui, je pense que c plus clean de faire comme cela. Par contre pourquoi while (1) et non pas if (1) ?
Marsh Posté le 02-04-2007 à 18:15:39
teycir a écrit : Oui, je pense que c plus clean de faire comme cela |
Décomposition du problème en opérations de bases. Plus souple comme moyen de faire...
teycir a écrit : Par contre pourquoi while (1) et non pas if |
while(1) => boucle infinie => tant que le gars ne rentre pas une date correcte, le bouzier lui repose la question
if (1) => super utile comme test...
Marsh Posté le 10-07-2007 à 14:14:08
Bonjour
Je ne commenterai pas la programmation car je suis un dinosaure, je programme en Basic!
Cependant j'ai réalisé un calendrier perpétuel qui me donne satisfaction, mon commentaire concerne les dates de réforme, qui sont différentes selon les pays et les religions:
Pour la France : 9 12 1582, le lendemain du 9 décembre étant le 20 décembre 1582.
Pour l'Angleterre : 2 9 1752, le lendemain du 2 septembre 1752 étant le 14 septembre 1752, l'écart entre calendriers ayant atteint 11 jours.
Pour la Russie, réforme en 1918 (je n'ai pas la date exacte) et la Grèce en 1923.
Le but de la réforme était effectivement de rétablir l'équinoxe de printemps à la date du 21 Mars, mais non pas comme elle était au début de l'ère chrétienne, ce que j'avais cru moi-même au départ, mais telle qu'elle était à je ne sais plus quel concile vers l'an 300 (pourquoi faire simple si on peut faire compliqué) cela pour le calcul de la date de Pâques.
Etablir le jour de la semaine d'une date, calculer la différence entre deux dates, c'est bien. A l'usage vient le désir d'ajouter ou soustraire un nombre de jours à une date pour en obtenir une nouvelle.
Ce n'est pas évident, je procède par approximations successives, une date "raisonnable" est évaluée, puis controlée (par exemple un 29 février est transformé en premier mars si l'année n'est pas bissextile) ensuite le module de différences de dates est appelé, un éventuel décalage est "rattrapé", avec contrôle secondaire.
Vous pourrez vérifier ainsi que le millionème jour de l'ère chrétienne sera le Samedi 26 Novembre 2738. Et vous ne passerez pas à côté de cet anniversaire. Ca serait dommage, non ?
Marsh Posté le 10-07-2007 à 20:13:56
Lizardo a écrit : Je ne commenterai pas la programmation car je suis un dinosaure, je programme en Basic! |
Ouaiiiiis !!! J'ai commencé comme ça. J'avais même réussi à implémenter la récursivité en Basic à coup de fichier que j'écris et que je vais relire ensuite
Lizardo a écrit : Le but de la réforme était effectivement de rétablir l'équinoxe de printemps à la date du 21 Mars, mais non pas comme elle était au début de l'ère chrétienne, ce que j'avais cru moi-même au départ, mais telle qu'elle était à je ne sais plus quel concile vers l'an 300 (pourquoi faire simple si on peut faire compliqué) cela pour le calcul de la date de Pâques. |
Ouaip. Rattrapper le décalage bissextile qui n'est pas vraiment tous les 4 ans mais tous les 4 ans, sauf tous les 100 ans mais quand-même tous les 400...
Lizardo a écrit : Ce n'est pas évident, je procède par approximations successives, une date "raisonnable" est évaluée, puis controlée (par exemple un 29 février est transformé en premier mars si l'année n'est pas bissextile) |
Oui. J'ai vu des fonctions php qui faisaient ça. En rentrant par exemple le 00/mm/yyyy, il ressort comme résultat <dernier jour>/mm -1/yyyy
Lizardo a écrit : Vous pourrez vérifier ainsi que le millionème jour de l'ère chrétienne sera le Samedi 26 Novembre 2738. Et vous ne passerez pas à côté de cet anniversaire. Ca serait dommage, non ? |
SUPAIRE !!!
Marsh Posté le 01-04-2007 à 10:50:33
Bonjour;
J'ai amélioré un code de calendrier perpétuel en C (de -2000 à 4000): affichage du jour de la semaine (lundi, mardi,mercredi...) en fonction de la date, mais il reste perfectible.
- Par exemple il y a des jours qui n'existent pas comme les 29 févriers des années non bissextiles qui sont affichées. Je voudrais que ces jours ne soient pas affichées (message d'erreur à la place).
- Il y a également un problème d'absence des heures et dates système à rajouter.
Je suis en train de plancher sur le code, si vous avez des solutions ou des astuces ou même des remarques quant à l'analyse, n'hésitez pas à me les communiquer.
Merci.
Voici le code du programme principal à perfectionner (rajout d'heure et de date système + élimination des jours n'ayant jamais existé comme les 29 févriers des années non bissextiles):
Voici un autre code auquel je souhaite me rapprocher (prise en compte des heures) en incluant le calcul du premier: