Découverte du langage ADA


Passer du jour julien à une date du calendrier grégorien

Un exemple pour comprendre à quoi cela peut servir.

La comète XXX passe à son périhélie tous les 14310 jours. Déterminer à quelle date correspond son prochain passage, sachant que le dernier s'est effectué au moment suivant :

Annee = 2012   Mois = 12    Jour    = 27 Heure = 11     minute = 45  Seconde = 46
Dans l'article précédent, nous avons calculé le jour julien :  2456288,990116
Si l'on ajoute 2456288,990116 et 14310, cela donne 2470598,990116
Mais à quelle date correspond ce nombre ?
L'algorithme de calcul est tiré de l'article de Wikipedia suivant.

Article de Wikipedia sur le jour julien

Cahier des charges :
Connaissant le jour julien, calculer la date correspondante du calendrier grégorien.
Le jour julien ne sera pas introduit dans le corps du programme mais saisi dans le déroulement de celui-ci.
Le résultat sera affiché en année, mois, jour décimal (contenant jours + partie fractionnaire correspondant à heure, minutes, secondes).

Description des calculs à effectuer.

La seule valeur à connaître est le jour julien (appelé JJulien par la suite).
Entiere=Tronq(JJulien)
Fractionnaire = JJulien-Entiere
Si Entiere inférieur à 2299161, afficher un message et interrompre le calcul.
Alfa = Tronq((Entiere - 1867216,25)/36524,25)
S = Entiere + 1 + Alfa - Tronq(Alfa/4)
B = S+1524,0
C = Tronq((B-122,1)/365,25)
D = Tronq(365,25*C)
E = Tronq((B-D)/30,6001)

Jour = B-D-Tronq(30.6001*E) + 0.5 + Fractionnaire
Si E <14 alors Mois = E- 1 sinon si E=14 ou  15 alors Mois = E - 13
Si Mois > 2 alors Annee = C - 4716 sinon Annee = C - 4715

Cette formule étant compliquée, les noms des variables S, B,... tels que définis dans le document de Wikipedia ont été conservés.

Calcul à la main à partir d'un exemple : on part de la valeur calculée précédemment, pour laquelle la date est connue.

JJulien = 2456288.990116
Entiere = Tronq(2456288.990116) = 2456288
Fractionnaire = 2456288.990116 - 2456288 = 0.990116 Alfa = Tronq ((2456288 -1867216.25)/36524.25) = 16 S = 2456288 + 1 + 16 - TRoq(16/4) = 2456301 B = 2456301 + 1524 = 2457825
C = Tronq((2457825 - 122.1)/365.25) = 6728
D = Tronq(365.25*6728) = 2457402
E = Tronq((2457825 - 2457402)/30.6001) = 13 Jour = 2457825 - 2457402 - TRonq(30.6001*13)+0.5+Fractionnaire = 27.490116
Mois = 12
Annee = 2012

Particularités de Ada à connaître avant de commencer

Un document de référence sur le langage Ada

1. Avant de pouvoir utiliser une constante, une variable, il faut définir son type.
2. L'affectation se fait en utilisant le signe := comme dans Pascal
Exemple : ma_variable := 50 ;
3. La fin d'une instruction est marquée par le point-virgule ; comme dans Pascal et d'autres langages.
4. Une opération entre des nombres ne peut se faire qu'entre des valeurs de même type
A := 12.45 / 2.7 ; est autorisé parce que les deux nombres sont de type float (nombres à virgules)
B := 12.45 / 3 ; est interdit parce que l'un des nombre est de type float et l'autre de type integer (nombre entier).

Conséquence de la quatrième affirmation

Le résultat final sera un nombre décimal, de type long_float, pour tenir compte de la précision requise.
Il s'ensuit que tous les nombres qui vont participer à ce résultat seront aussi de type long_float.

Conséquence des affirmations 1 et 2

On définit les variables :
   Annee     :  long_float ;        Mois     :  long_float ;
   Jour         :  long_float ;        Entieres :  long_float ;
   Fractionnaire :  long_float ;        Alfa     :  long_float ;
S , B , C , D , E : long_float ;
JJulien : long_float ;
Avant de les initialiser :
   Annee    := 0.0 ;    Mois     := 0.0 ;
   Jour     := 0.0 ;      ...
   JJulien  := 0.0 ;
Le jour julien est alors saisi en utilisant une fonction, conformément au cahier des charges.

Nouveauté par rapport au programme précédent

Le code source du programme étant accessible à la fin de cet article, nous allons commenter ici seulement ce qui est nouveau :
- la saisie d'une variable
- la non exécution en cas de valeur trop petite.

Saisie d'une valeur

Celle-ci est déportée dans une function afin d'alléger le code de la procédure principale.

function SaisieJJ return long_float is
-- la saisie du Jour Julien est déportée dans une fonction
prov : long_float; -- valeur locale pour la saisie
begin
  prov:=0.0;
  Put("Calcul d'une date du calendrier grégorien en partant du Jour Julien");
 New_Line ; Put("--------------------------------------------------------------------");
New_Line ; Put("Entrer le Jour Julien, la partie décimale"); New_Line ; Put("et la partie entière étant séparées par un point : "); Get(prov); return prov; -- retour de la valeur saisie
end SaisieJJ ;
La non exécution en cas de valeur trop petite
Elle s'effectue dans le corps de la procédure principale selon la logique suivante :
if JJulien > 2299161.0
  then
     effectuer les calculs et afficher les résultats
...
  else
signaler l'erreur
end if ;
Ce qui est une façon très minimaliste de traiter le problème.
Par la suite, on verra comment faire mieux.

Et maintenant ?

Le code du programme peut être chargé ici :
Code à charger
Il se compile en tapant dans une fenêtre console (Linux ou Windows):

gnatmake jjul_gregor.adb
qui génère un code exécutable que l'on peut lancer en tapant :
./jjul_gregor
ou
jjul_gregor

La suite plus tard...


Merci à octave.org: le mode de fonctionnement de ce site m'ayant plu, je
m'en suis largement inspiré (=je l'ai carrément pompé) pour ces quelques pages.