source: Sophya/trunk/SophyaLib/NTools/datime.c@ 3856

Last change on this file since 3856 was 3205, checked in by ansari, 18 years ago

Suppression flags MWERKS (compilo CodeWarrior pour MacOS8,9) , Reza 10/04/2007

File size: 36.2 KB
Line 
1#include "machdefs.h"
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5#include <ctype.h>
6#include <math.h>
7
8
9#define DATIMEPRIVEE
10#include "strutil.h"
11#include "nbconst.h"
12#include "datime.h"
13
14
15/* Fonctions de calcule de date et temps (Heure) */
16/*!
17 \ingroup NTools
18 \file datime.c
19 \brief Set of C functions and macros to manipulate date and time + Sidereal time
20 and simple astronomical functions.
21
22 \warning If possible, use class SOPHYA::TimeStamp in module BaseTools
23 for date/time computation.
24
25 Ce groupe de fonctions permettent de manipuler des dates et heures.
26 En particulier, il est possible de calculer l'ecart (en nombre de jours
27 ou de secondes separant deux dates, ou le temps sideral correspondant
28 a une date et heure legale. Deux structures simples sont definies
29 afin de faciliter le passage des arguments entre differentes fonctions:
30 - JMA : Jour, Mois, Annee
31 - HMS : Heure, Minutes, Secondes
32
33 \sa SOPHYA::TimeStamp
34*/
35
36/*
37++
38 StrgtoJMA(strg, jma)
39 Decodage d'une chaine de caracteres "strg" sous forme de "12/3/97" en structure
40 JMA "jma".
41 JMAtoStrg(jma, strg)
42 Ecrit le contenu de la structure JMA "jma" sous forme de "jj/mm/aaaa" dans la chaine
43 de caracteres "strg"
44 JMAtoStrgLong(jma, strg)
45 Ecriture de date en format long , par ex : "Jeudi , 19 Juin 1997"
46 StrgtoHMS(strg, hms)
47 Decodage d'une chaine de caracteres "strg" sous forme de "hh:mm:ss 10:43:60.5"
48 en structure HMS "hms".
49 HMStoStrg(hms, strg)
50 Ecrit le contenu de la structure HMS "hms" sous forme de "hh:mm:ss" dans la chaine
51 de caracteres "strg"
52 StrtoHMS(strg, hms)
53 Decodage d'une chaine de caracteres "strg" sous forme de "hh:mm:ss 10:43:60.5"
54 en structure HMS "hms" avec gestion des signes (decodage correcte de -44:30:05.23)
55 HMStoStr(hms, strg)
56 Ecrit le contenu de la structure HMS "hms" sous forme de "hh:mm:ss" dans la chaine
57 de caracteres "strg" avec gestion des signes
58--
59*/
60/*!
61 \ingroup NTools
62 Decodage d'une chaine de caracteres "strg" sous forme de "hh:mm:ss 10:43:60.5"
63 en structure HMS "hms" avec gestion des signes (decodage correcte de -44:30:05.23)
64*/
65void StrtoHMS(char *s,HMS* h)
66/* On ne peut pas ecrire 1:-05:-45 pas gere et debile! (mn et sec >=0.) cmv 12/8/97 */
67{
68int imoins, i2pt;
69h->Heures = h->Minutes = 0; h->Secondes = 0.;
70/* decodage de la chaine de characteres */
71sscanf(s,"%d:%d:%lf", &(h->Heures),&(h->Minutes),&(h->Secondes));
72/* cas du type 5:34:45.5 */
73if( h->Heures > 0 ) return;
74/* cas du type -5:34:45.5 */
75if( h->Heures < 0 ) {
76 h->Minutes *= -1; h->Secondes *= -1.;
77 return;
78}
79/* Ici les Heures sont donc nulles "0:..." ou "-0:..." */
80/* on n'a donne que l'heure nulle cas "0" ou "-0" sans ":" (idiot mais bon!) */
81i2pt = posc(s,':');
82if( i2pt < 0 ) return;
83/* Ici on a au moins un ou 2 ":" */
84/* cas du type 0:34:45.5 ou 0:0:45.5 sans signe - */
85imoins = posc(s,'-');
86if( imoins < 0 ) return;
87/* cas du type -0:34:45.5 ou -0:0:45.5, le signe - n'est pas decode par sscanf */
88if( imoins < i2pt ) { /* on a donne -0:34 ou -0:34:45.5 */
89 h->Minutes *= -1; h->Secondes *= -1.;
90 return;
91}
92/* Ici il reste les cas mal codes ou le signe "-" est n'importe ou! */
93/* On laisse le decodage par sscanf */
94return;
95}
96
97/*!
98 \ingroup NTools
99 Ecrit le contenu de la structure HMS "hms" sous forme de "hh:mm:ss" dans la chaine
100 de caracteres "strg" avec gestion des signes
101*/
102void HMStoStr(HMS h,char *s)
103/* L'ecriture est forcee a h:mn:sec avec mn et sec >=0 cmv 12/8/97 */
104{
105double v;
106v = HMStoH(h);
107h = DoubletoHMS(v);
108if( v < 0. ) {
109 h.Heures *= -1; h.Minutes *= -1; h.Secondes *= -1.;
110 sprintf(s,"-%02d:%02d:%04.1f", h.Heures,h.Minutes,h.Secondes);
111} else {
112 sprintf(s,"%02d:%02d:%04.1f", h.Heures,h.Minutes,h.Secondes);
113}
114}
115
116/* Nouvelle-Fonction */
117/*!
118 \ingroup NTools
119 \brief Retourne le nombre de jours dans le mois m, annee a
120*/
121int NbJourMois(int a, int m)
122/* Retourne le nombre de jours dans le mois m, annee a */
123{
124if(a<100) a+=1900;
125if( m<1 || m>12 ) return(-1);
126m--;
127if(m!=1) return(NbJoMois[m]);
128/* traitement du mois de fevrier bissextile ou non */
129if( ((a%4==0) && (a%100!=0))
130 || (a%400==0) ) return(NbJoMois[m]+1);
131else return(NbJoMois[m]);
132}
133
134/*!
135 \ingroup NTools
136 Calcule le Nombre de jours ecoules depuis 0 Jan 1901.
137 Si annee < 100 On considere annee = annee+1900 (1900-1999)
138*/
139/* Nouvelle-Fonction */
140long JMAtoJ(JMA jma)
141{
142long rc,nban;
143int i;
144
145/* Protection */
146if ( (jma.Mois < 1) || (jma.Mois > 12) ) jma.Mois = 1;
147if ( (jma.Jour < 1) || (jma.Jour > 31) ) jma.Jour = 1;
148
149if (jma.Annee < 100) jma.Annee+=1900;
150nban = jma.Annee - 1901;
151
152/* Annee Normale = 365 Jours - Bissextile = 366 Jours */
153/* 366 Jours : Divisible par 4 et non divisible par 100 (1972,1976) */
154/* : Divisible par 400 (1900 Non-Biss. et 2000 Biss.) */
155
156if (nban >= 0)
157 rc = nban*365 + (nban/4) - (nban/100) + ((nban+300)/400);
158else
159 rc = nban*365 + (nban/4) - (nban/100) + ((nban-300)/400);
160
161/* Comptabilisation du nb. des jours des mois ecoule */
162for (i=1; i<jma.Mois; i++) rc += NbJourMois(jma.Annee, i);
163rc += jma.Jour;
164
165return(rc);
166}
167
168/*!
169 \ingroup NTools
170 \brief retourne la date correspondant a \b j jours ecoules depuis le 0/1/1901
171*/
172/* Nouvelle-Fonction */
173JMA JtoJMA(long j)
174{
175long i;
176int inc,m;
177JMA buf;
178
179inc = (j>=0) ? 1 : -1;
180buf.Jour = buf.Mois = 1; buf.Annee = 1901;
181
182/* recherche de l'annee */
183for(;;) {
184 i = j-JMAtoJ(buf);
185 if( i==0 ) return(buf);
186 if( inc*i<0 ) {
187 /* printf("...annee j=%ld scan=%ld test=%ld\n"
188 ,j,JMAtoJ(buf),inc*i); */
189 break;
190 }
191 buf.Annee += inc;
192}
193if(inc>0) buf.Annee--;
194/* printf("Annee trouvee: %d\n",buf.Annee); */
195
196/* recherche du mois */
197for(m=1;m<=12;m++) {
198 buf.Mois=m;
199 i = j-JMAtoJ(buf);
200 if( i==0 ) return(buf);
201 if(i<0) {
202 /* printf("...mois j=%ld scan=%ld test=%ld\n"
203 ,j,JMAtoJ(buf),i); */
204 buf.Mois--;
205 break;
206 }
207}
208/* printf("Mois trouve: %d\n",buf.Mois); */
209
210/* recherche du jour */
211for(m=1;m<=31;m++) {
212 buf.Jour=m;
213 i = j-JMAtoJ(buf);
214 if( i==0 ) return(buf);
215}
216/* printf("Jour trouve: %d\n",buf.Jour); */
217
218/* on a pas trouve !!! normallement impossible! */
219printf("**** JtoJMA_Erreur: date non trouvee j=%ld ****\n",j);
220buf.Jour = buf.Mois = 1; buf.Annee = 0;
221return(buf);
222}
223
224/*!
225 \ingroup NTools
226 \brief Cette fonction calcule le numero de jour de la semaine (Lundi=1 .. Dimanche=7)
227*/
228/* Nouvelle-Fonction */
229int NumJour(JMA jma)
230{
231int l;
232
233/* On appelle JMAtoJ() pour avoir le nb de jours ecoule depuis 1/01/1901 */
234/* Le premier janvier 1901 etait un Mardi (JMAtoJ = 1 , NumJour = 2) */
235l = JMAtoJ(jma)%7 ;
236if (l >= 0) return(l+1);
237else return(l+8);
238}
239
240/* Nouvelle-Fonction */
241JMA JsmmaatoJMA(int nj, int mm, int aa)
242
243/* Pour "nj=kj*10+jj", calcule la date correspondant au "kj" eme
244 jour "jj" (1 .. 7 - Lundi .. Dimanche) du mois mm , annee aa
245 Si "nj" est negatif -> Dernier jour "jj". Si "kj=0", premier jour "jj".
246 Si "kj" ne peut etre atteint -> Dernier jour "jj".
247 Si annee "aa" <= 99 -> annee de 1901 - 1999 */
248
249{
250JMA jma;
251int i,k;
252int jj, kj;
253
254kj = nj/10;
255jj = nj%10;
256if (kj < 0) kj = 0;
257
258if (mm > 12) mm = 12;
259if (mm < 1 ) mm = 1;
260if (aa < 100) aa += 1900;
261jma.Mois = mm;
262jma.Annee = aa;
263
264if (kj == 0) {
265 if (jj >= 0) { /* Premier jour du mois */
266 if (jj > 7) jj = 7;
267 if (jj < 1) jj = 1;
268 jma.Jour = 1;
269 i = NumJour(jma);
270 if (i > jj) jma.Jour = (7-i)+jj+1;
271 else jma.Jour = 1+(jj-i);
272 }
273 else { /* Dernier jour du mois */
274 jj = -jj;
275 if (jj > 7) jj = 7;
276 if (jj < 1) jj = 1;
277 jma.Jour = NbJourMois(aa,mm);
278 i = NumJour(jma);
279 if (i >= jj) jma.Jour -= (i-jj);
280 else jma.Jour -= (7+i-jj);
281 }
282}
283else { /* On demande le kj eme jour jj du mois */
284 if (jj > 7) jj = 7;
285 if (jj < 1) jj = 1;
286 k = 0;
287 for(i=1; i<=NbJourMois(aa,mm); i++) {
288 jma.Jour = i;
289 if (NumJour(jma) == jj) k++;
290 if (k == kj) break;
291 }
292/* On n'a pas kj jour jj ds ce mois, on renvoie le dernier jj */
293 if (k<kj) return(JsmmaatoJMA(-jj, mm, aa));
294}
295
296return(jma);
297}
298
299/*!
300 \ingroup NTools
301 Pour "nj=dd*10+jj", calcule la date correspondant au jour
302 "jj" (1 .. 7 - Lundi .. Dimanche) du mois "mm" , annee "aa"
303 se trouvant apres (ou egal a) la date "dd/mm/aa" .
304 Si annee "aa" <= 99 -> annee de 1901 - 1999
305*/
306JMA JApmmaatoJMA(int nj, int mm, int aa)
307{
308int i, dd, jj;
309JMA jma;
310
311if (nj < 0) nj = -nj;
312if (nj < 1) nj = 1;
313dd = nj/10;
314jj = nj%10;
315for(i=1; i<=6; i++) {
316 jma = JsmmaatoJMA(jj+10*i, mm, aa);
317 if(jma.Jour >= dd) return(jma);
318}
319printf("JApmmaatoJMA(%d...) Erreur / Pas de jour %d >= %d/%d/%d\n", nj, jj,dd, mm, aa);
320jma.Jour = jma.Mois = jma.Annee = 0;
321return(jma);
322}
323
324/*!
325 \ingroup NTools
326 Cette fonction calcule le nombre d'heures en decimales pour \b hms.
327 Heures/Minutes/Secondes peuvent etre +/- avec toutes les combinaisons possibles
328*/
329/* Nouvelle-Fonction */
330double HMStoH(HMS hms)
331
332/* Cette fonction calcule le nb d'heures en decimales pour hms */
333/* Heures/Minutes/Secondes peuvent etre +/- avec toutes les combi possibles */
334{
335return ((double)hms.Heures + ((double)hms.Minutes)/60. + hms.Secondes/3600.);
336}
337
338
339/*!
340 \ingroup NTools
341 \brief Conversion en secondes de la structure HMS "hms"
342*/
343/* Nouvelle-Fonction */
344double HMStoSec(HMS hms)
345/* Calcul du nb de secondes pour hms */
346/* Heures/Minutes/Secondes peuvent etre +/- avec toutes les combi possibles */
347{
348return ((double)hms.Heures*3600. + (double)hms.Minutes*60. + hms.Secondes);
349}
350
351/*!
352 \ingroup NTools
353 Calcule le nombre de secondes correspondant a "date,heure"
354 a partir de l'origine 1er Janv 1990 0H00 ( Date entre 1930 - 2050 )
355*/
356/* Nouvelle-Fonction */
357long DatetoSec(char const* date, char const* heure)
358/* Calcul du nombre de secondes correspondant a date/heure */
359/* a partir de l'origine 1er Janv 1990 0H00 */
360/* Date entre 1930 - 2050 */
361{
362JMA jma,jma0;
363HMS hms;
364long dj;
365
366StrgtoJMA(date,jma); StrgtoHMS(heure,hms);
367StrgtoJMA("01/01/1990",jma0);
368dj = JMAtoJ(jma) - JMAtoJ(jma0);
369if (dj < -24000) return(-0x7FFFFFFF);
370if (dj > 24000) return(0x7FFFFFFF);
371return( dj*3600*24 + (int)(HMStoSec(hms)) );
372}
373
374/*!
375 \ingroup NTools
376 Calcule le nombre de secondes correspondant a "date,heure"
377 a partir de l'origine 1er Janv 1990 0H00 ( Date entre 1930 - 2050 )
378 en tenant compte des decalages des heures legales.
379*/
380/* Nouvelle-Fonction */
381long DatetoSecOff(char const* date, char const* heure)
382{
383JMA jma,jma0;
384HMS hms, hms0;
385long dj,tdec;
386
387StrgtoJMA(date,jma); StrgtoHMS(heure,hms);
388StrgtoJMA("01/01/1990",jma0); StrgtoHMS("00:00:00",hms0);
389dj = JMAtoJ(jma) - JMAtoJ(jma0);
390if (dj < -24000) return(-0x7FFFFFFF);
391if (dj > 24000) return(0x7FFFFFFF);
392
393/* H_vrai+TOff=H_leg : H_vrai-H_vrai0 = (H_leg-TOff)-(H_leg0-TOff0) */
394tdec = 3600*(TLegOffset(jma, hms)-TLegOffset(jma0, hms0));
395
396dj = dj*3600*24 + (int)(HMStoSec(hms)) - tdec;
397return(dj);
398}
399
400/*!
401 \ingroup NTools
402 \brief Conversion heures en decimales en structure HMS
403*/
404/* Nouvelle-Fonction */
405HMS HtoHMS(double h)
406/* Heures decimales en H , M , Sec Il y a un modulo 24 */
407/* la sortie est telle que 0 <= heures < 24 */
408{
409HMS hms;
410
411while (h < 0.) h += 24.;
412
413hms.Heures = (int) h;
414h = (h-hms.Heures)*60.;
415hms.Minutes = (int) h;
416hms.Secondes = (h-hms.Minutes)*60.;
417hms.Heures = hms.Heures % 24;
418
419return(hms);
420}
421
422/*!
423 \ingroup NTools
424 Conversion degres decimaux en structure HMS (deg,min,sec)
425 Degres decimaux en D , M , Sec Il y a un modulo 360.
426 la sortie est telle que -180 < deg <= 180.
427*/
428/* Nouvelle-Fonction */
429HMS DtoDMS(double h)
430{
431HMS hms;
432int sgn = 1;
433
434while (h > 180.) h -= 360.;
435while (h <= -180.) h += 360.;
436if( h < 0. ) {h *= -1.; sgn = -1;}
437
438hms.Heures = (int) h;
439h = (h-hms.Heures)*60.;
440hms.Minutes = (int) h;
441hms.Secondes = (h-hms.Minutes)*60.;
442hms.Heures = hms.Heures % 360;
443
444if( sgn<0 ) {hms.Heures *= -1; hms.Minutes *= -1; hms.Secondes *= -1.;}
445return(hms);
446}
447
448/*!
449 \ingroup NTools
450 Conversion degres/heures decimaux en structure HMS (deg/heure,min,sec)
451 SANS modulo 360/24
452*/
453/* Nouvelle-Fonction */
454HMS DoubletoHMS(double h)
455/* Degres/Heures decimaux en D/H , M , Sec SANS modulo 360/24 */
456{
457HMS hms;
458
459int sgn = 1;
460if( h < 0. ) {h *= -1.; sgn = -1;}
461
462hms.Heures = (int) h;
463h = (h-hms.Heures)*60.;
464hms.Minutes = (int) h;
465hms.Secondes = (h-hms.Minutes)*60.;
466hms.Heures = hms.Heures;
467
468if( sgn<0 ) {hms.Heures *= -1; hms.Minutes *= -1; hms.Secondes *= -1.;}
469return(hms);
470}
471
472/*
473++
474 Titre Calcule sur dates et heures
475--
476*/
477
478/*
479++
480int NbJourMois(int a, int m)
481 Retourne le nombre de jours dans le mois "m", annee "a".
482long JMAtoJ(JMA jma)
483 Calcule le Nb. de jours ecoules depuis 0 Jan 1901,
484 Si annee < 100 On considere annee = annee+1900 (1900-1999)
485JMA JtoJMA(long j)
486 Retourne la date correspondant a un nombre de jours "j"
487 ecoules depuis le 0 Jan 1901.
488int NumJour(JMA jma)
489 Calcule le numero du jour de la semaine correspondant a la date indiquee
490 par la structure JMA "jma". (Lundi=1 .. Dimanche=7)
491JMA JsmmaatoJMA(int nj, int mm, int aa)
492 Pour "nj=kj*10+jj", calcule la date correspondant au "kj" eme
493 jour "jj" (1 .. 7 - Lundi .. Dimanche) du mois mm , annee aa
494 Si "nj" est negatif -> Dernier jour "jj". Si "kj=0", premier jour "jj".
495 Si "kj" ne peut etre atteint -> Dernier jour "jj".
496 Si annee "aa" <= 99 -> annee de 1901 - 1999
497JMA JApmmaatoJMA(int nj, int mm, int aa)
498 Pour "nj=dd*10+jj", calcule la date correspondant au jour
499 "jj" (1 .. 7 - Lundi .. Dimanche) du mois "mm" , annee "aa"
500 se trouvant apres (ou egal a) la date "dd/mm/aa" .
501 Si annee "aa" <= 99 -> annee de 1901 - 1999
502double HMStoH(HMS hms)
503 Conversion en heures decimales de la structure "hms"
504double HMStoSec(HMS hms)
505 Conversion en secondes de la structure HMS "hms"
506HMS HtoHMS(double h)
507 Conversion heures en decimales en structure HMS
508HMS DtoDMS(double h)
509 Conversion degres decimaux en structure HMS (deg,min,sec)
510HMS DoubletoHMS(double h)
511 Conversion degres/heures decimaux en structure HMS (deg/heure,min,sec)
512 SANS modulo 360/24
513long DatetoSec(char const* date, char const* heure)
514 Calcule le nombre de secondes correspondant a "date,heure"
515 a partir de l'origine 1er Janv 1990 0H00 ( Date entre 1930 - 2050 )
516long DatetoSecOff(char const* date, char const* heure)
517 Calcule le nombre de secondes correspondant a "date,heure"
518 a partir de l'origine 1er Janv 1990 0H00 ( Date entre 1930 - 2050 )
519 en tenant compte des decalages des heures legales.
520--
521*/
522
523
524
525/* Variables contenant les informations pour conversion */
526/* Temps Legal <> TU <> Temps solaire moyen */
527
528static double TSolMOff = 0.; /* TSol.Moyen - TU (en heures) */
529static char SiteName[128]; /* Nom de site */
530
531static struct
532 {
533 char fg; /* Flag (=A ou B) Type de specification */
534 int jj[2]; /* Numero ou date du jour */
535 int mm[2]; /* Mois */
536 int Off[3]; /* Decalage = TLegal - TU */
537 } TLegInfo = {'\0',{0,0},{0,0},{0,0,0}} ;
538
539static HMS HChgH = {0,0,0.} ; /* Heure de changement d'heure */
540
541/*
542++
543 Module Temps Sideral, Universel (C)
544 Lib LibsUtil
545 include datime.h
546
547 Ce groupe de fonctions permet convertir differentes heures:
548 les temps local, le temps universel (TU), le temps legal (TLeg). Il est
549 aussi possible de calculer le temps sideral (TS).
550--
551*/
552/*
553++
554 Links Voir aussi:
555 Dates (C)
556--
557*/
558/*
559++
560 Titre T-Legal, TU
561 Conversion entre l'heure legale, le temps universel (TU) et le temps solaire
562 moyen
563--
564*/
565
566/*
567++
568SetTSolMOff(double tsmoff, char *name)
569 Definit pour un site donne, le decalage T Sol. Moyen - TU (en heures) "tmsoff"
570 et le nom du site
571PrtTSolMOff()
572 Imprime les infos definis par "SetTSolMOff()"
573--
574*/
575
576/* Nouvelle-Fonction */
577void SetTSolMOff(double tsmoff, char *name)
578
579/* Offset T Sol. Moyen - TU (en hh:mm:ss) , Nom de site name */
580{
581TSolMOff = tsmoff;
582strcpy(SiteName,name);
583return;
584}
585
586
587/* Nouvelle-Fonction */
588void PrtTSolMOff(void)
589{
590printf(" **Site : %s , T Sol.Moy.-TU %g (heures) \n",SiteName,TSolMOff);
591return;
592}
593
594/*
595++
596int SetTLegOff(char* dtz, char* dhz)
597 Initialise la structure TLegInfo. L'argument *dtz peut etre
598 sous 2 forme differentes et permet de definir 3 plages
599 de temps avec 3 decalages horaires (nb entier).
600 Les dates pivots sont les jours de changement d'heure a
601 l'heure indiquee par dhz ("hh:mm:ss"), si "dhz==NULL ou
602 chaine vide, alors changement a 0 heure.
603| 1) dtz = "A Off1 j1/m1 Off2 j2/m2 Off3"
604| jx/mx Jour/Mois - Offx : Decalage TLeg - TU
605| pour 01/01 <= jj/mm < j1/m1 -> Off1
606| j1/m1 <= jj/mm < j2/m2 -> Off2
607| j2/m2 <= jj/mm <= 31/12 -> off3
608| 2) dtz = "B off1 Js1/m1 Off2 Js2/m2 Off3"
609| Jsx/mx Numero du jour de la semaine (Js) et numero du mois
610| Js = 1 .. 7 (Lundi .. Dimanche) : 1er Jour Js du mois
611| = -1 .. -7 Dernier jour Js du mois
612| = k1 .. k7 k eme jour Js du mois
613| 3) dtz = "C off1 Js1/m1 Off2 Js2/m2 Off3"
614| Jsx/mx Numero du jour de la semaine (Js) et numero du mois avec une
615| precision d'une date butee inferieurs
616| Js = ddj .. (j=1..7 Lundi .. Dimanche) : 1er Jour j du mois
617| apres (ou egal a) la date dd/mm
618 Retour : 0 si Ok -1 Sinon
619void PrtTLegInfo(int aa)
620 Imprime les informations de decalage TLeg , TU - Annee "aa"
621int TLegOffset(JMA date, HMS heure)
622 Indique le decalage (en nombre d'heures) TLeg-TU
623--
624*/
625
626/* Nouvelle-Fonction */
627int SetTLegOff(char* dtz, char* dhz)
628
629
630{
631int is;
632
633HChgH.Heures = HChgH.Minutes = 0;
634HChgH.Secondes = 0.;
635
636if (dhz) StrgtoHMS(dhz, HChgH);
637if ( (HChgH.Heures < 0) || (HChgH.Heures > 23) )
638 { HChgH.Heures = HChgH.Minutes = 0; HChgH.Secondes = 0.; }
639
640is = sscanf(dtz,"%c %d %d/%d %d %d/%d %d", &(TLegInfo.fg), &(TLegInfo.Off[0]), &(TLegInfo.jj[0]), &(TLegInfo.mm[0]), &(TLegInfo.Off[1]), &(TLegInfo.jj[1]), &(TLegInfo.mm[1]), &(TLegInfo.Off[2]) );
641
642if ( (TLegInfo.fg != 'A') && (TLegInfo.fg != 'B')
643 && (TLegInfo.fg != 'C') ) TLegInfo.fg = '\0';
644if (is != 8) TLegInfo.fg = '\0';
645if (TLegInfo.fg != '\0') return(0);
646else { printf("SetTLegOff()/Erreur %s \n", dtz); return(-1); }
647}
648
649/* Nouvelle-Fonction */
650void PrtTLegInfo(int aa)
651
652/* Cette fonction print les infos de TLegInfo */
653{
654int i,k,j;
655char ForL[2][128];
656JMA jma;
657
658if (TLegInfo.fg == '\0') printf (" !!! TlegInfo not set or Error \n");
659
660
661HMStoStrg(HChgH, ForL[0]);
662printf(" ==== TLegInfo : Changement d'heure a %s \n", ForL[0]);
663ForL[0][0] = '\0';
664if (TLegInfo.fg == 'A')
665 {
666 printf(" ---- TLegInfo : Selection par date (Flag = A) ---- \n");
667 printf(" -> 01 Janvier - %d %s : %d heures \n",TLegInfo.jj[0], NomMo[TLegInfo.mm[0]-1], TLegInfo.Off[0]);
668 printf(" -> %d %s - %d %s : %d heures \n",TLegInfo.jj[0], NomMo[TLegInfo.mm[0]-1],TLegInfo.jj[1], NomMo[TLegInfo.mm[1]-1],TLegInfo.Off[1]);
669 printf(" -> %d %s - 31 Decembre : %d heures \n",TLegInfo.jj[1], NomMo[TLegInfo.mm[1]-1], TLegInfo.Off[2]);
670 }
671
672if (TLegInfo.fg == 'B')
673 {
674 printf(" --- TLegInfo : Selection par Jour de semaine et mois (Flag = B) --- \n");
675 for (i=0;i<2;i++) {
676 k = TLegInfo.jj[i]/10;
677 if (k < 1) k = 1;
678 j = TLegInfo.jj[i]%10;
679 if (j < 0) j = -j;
680 if (j < 1) j = 1;
681 if (j > 7) j = 7;
682 if (TLegInfo.jj[i] < 0) sprintf(ForL[i]," Dernier %s de %s (KJ=%d)", NomJo[j-1],
683 NomMo[TLegInfo.mm[i]-1], TLegInfo.jj[i]);
684 else sprintf(ForL[i]," %d eme %s de %s (KJ=%d)", k, NomJo[j-1],
685 NomMo[TLegInfo.mm[i]-1], TLegInfo.jj[i]);
686 }
687 printf(" Butees: %s - %s \n", ForL[0], ForL[1]);
688 for (i=0;i<2;i++) {
689 jma = JsmmaatoJMA(TLegInfo.jj[i], TLegInfo.mm[i], aa);
690 JMAtoStrg(jma, ForL[i]);
691 }
692 printf(" -> 01 Janvier %d - %s : %d heures \n",aa, ForL[0], TLegInfo.Off[0]);
693 printf(" -> %s - %s : %d heures \n",ForL[0], ForL[1], TLegInfo.Off[1]);
694 printf(" -> %s - 31 Decembre %d : %d heures \n",ForL[1], aa, TLegInfo.Off[2]);
695 }
696
697if (TLegInfo.fg == 'C')
698 {
699 printf(" --- TLegInfo : Selection par Jour de semaine >= dd et mois (Flag = C) --- \n");
700 for (i=0;i<2;i++) {
701 k = TLegInfo.jj[i]/10;
702 j = TLegInfo.jj[i]%10;
703 if (j < 0) j = -j;
704 if (j < 1) j = 1;
705 if (j > 7) j = 7;
706 sprintf(ForL[i],"1er %s apres le %d %s ", NomJo[j-1], k, NomMo[TLegInfo.mm[i]-1]);
707 }
708 printf(" Butees: %s - %s \n", ForL[0], ForL[1]);
709 for (i=0;i<2;i++) {
710 jma = JApmmaatoJMA(TLegInfo.jj[i], TLegInfo.mm[i], aa);
711 JMAtoStrg(jma, ForL[i]);
712 }
713 printf(" -> 01 Janvier %d - %s : %d heures \n",aa, ForL[0], TLegInfo.Off[0]);
714 printf(" -> %s - %s : %d heures \n",ForL[0], ForL[1], TLegInfo.Off[1]);
715 printf(" -> %s - 31 Decembre %d : %d heures \n",ForL[1], aa, TLegInfo.Off[2]);
716 }
717
718return;
719}
720
721
722/* Nouvelle-Fonction */
723int TLegOffset(JMA date, HMS heure)
724
725/* Cette fonction calcule l'offset TLeg - TU pour la date donnee date */
726{
727JMA jma1,jma2;
728long nbj1,nbj2,nbj;
729double decj1, decj2, decj;
730int Off;
731
732/* On recherche l'offset correspondant a la date */
733jma1.Annee = jma2.Annee = date.Annee;
734if (TLegInfo.fg == 'A')
735/* Periode defini par des dates ds les mois */
736 {
737 jma1.Mois = TLegInfo.mm[0];
738 jma1.Jour = TLegInfo.jj[0];
739 jma2.Mois = TLegInfo.mm[1];
740 jma2.Jour = TLegInfo.jj[1];
741 }
742if (TLegInfo.fg == 'B')
743/* Periodes definies par jour de semaine et mois */
744 {
745 jma1 = JsmmaatoJMA(TLegInfo.jj[0],TLegInfo.mm[0],date.Annee);
746 jma2 = JsmmaatoJMA(TLegInfo.jj[1],TLegInfo.mm[1],date.Annee);
747 }
748
749if (TLegInfo.fg == 'C')
750/* Periodes definies par jour de semaine et mois avec date inferieure */
751 {
752 jma1 = JApmmaatoJMA(TLegInfo.jj[0],TLegInfo.mm[0],date.Annee);
753 jma2 = JApmmaatoJMA(TLegInfo.jj[1],TLegInfo.mm[1],date.Annee);
754 }
755
756nbj = JMAtoJ(date);
757nbj1 = JMAtoJ(jma1);
758nbj2 = JMAtoJ(jma2);
759
760/* Les dates pivots sont les jours de changement d'heure a Heure= HChgH */
761decj = (double)nbj + HMStoH(heure)/24.;
762decj1 = (double)nbj1 + HMStoH(HChgH)/24.;
763decj2 = (double)nbj2 + HMStoH(HChgH)/24.;
764
765if ( decj < decj1 ) Off = TLegInfo.Off[0];
766else if (decj < decj2) Off = TLegInfo.Off[1];
767 else Off = TLegInfo.Off[2];
768
769/* Impression de debugging */
770/*Debug-- printf (" @@@ Debug_TLegOffset (date= %d/%d/%d) : %d H. \n",date.Jour,date.Mois,date.Annee,Off);
771printf(" @-1 %s , %d %s %d \n", NomJo[NumJour(jma1)-1], jma1.Jour, NomMo[jma1.Mois-1], jma1.Annee) ;
772printf(" @-2 %s , %d %s %d \n", NomJo[NumJour(jma2)-1], jma2.Jour, NomMo[jma2.Mois-1], jma2.Annee) ; --*/
773
774
775return (Off);
776}
777
778/*
779++
780HMS TLegtoTU(JMA date, HMS TLeg)
781 Conversion TLegal en TU pour une date donnée
782HMS TUtoTLeg(JMA date, HMS TLeg)
783 Conversion TU en TLegal pour une date donnée. L'heure légale calculée
784 peut être erronnée autour des dates de changement d'heure.
785HMS TUtoTSolM(HMS TU)
786 Conversion TU en temps solaire moyen
787--
788*/
789
790/* Nouvelle-Fonction */
791HMS TLegtoTU(JMA date, HMS hmsz)
792
793/* Cette fonction transforme le temps legal en temps universel */
794{
795HMS TU;
796int Off;
797
798Off = TLegOffset(date, hmsz);
799TU = hmsz;
800TU.Heures -= Off;
801if (TU.Heures >= 24) TU.Heures -= 24;
802if (TU.Heures < 0) TU.Heures += 24;
803return(TU);
804}
805
806
807
808/* Nouvelle-Fonction */
809HMS TUtoTLeg(JMA date, HMS hms)
810
811/* Cette fonction transforme le temps universel en temps legal */
812{
813HMS TLeg;
814int Off;
815
816Off = TLegOffset(date, hms); /* $CHECK$ */
817TLeg = hms;
818TLeg.Heures += Off;
819TLeg.Heures = TLeg.Heures%24;
820if (TLeg.Heures < 0) TLeg.Heures += 24;
821return(TLeg);
822}
823
824
825/* Nouvelle-Fonction */
826HMS TUtoTSolM(HMS TU)
827
828/* Passage TU -> Temps local */
829{
830double t;
831t = HMStoH(TU) + TSolMOff;
832return(HtoHMS(t));
833}
834
835/*
836++
837 Titre Temps Sideral
838| Jour Sideral = 86400 Sec. Sid. ( = 24 H Sid. )
839| Annee Solaire = 365 J 5H 48' 46" =~ 365.2422 J
840| Annee Solaire = 365.2422 Jours Solaire Moyen = 366.2422 Jours Sideraux
841| Jour Sol. Moyem = 24 H Sol. = 24 H Sid. * (366.2422 / 365.2422)
842| Jour Solaire Moyen = 86636.555359 Sec. Sid. = 24 H 3' 56.555359"
843| Heure Solaire Moyen = 3609.85647 Sec. Sid.
844| Sec. Sol. = 1.0027379 Sec. Sid.
845| Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral
846--
847*/
848
849/*
850++
851HMS TLegtoTSid(JMA date, HMS TZ)
852 Cette fonction calcule le temps sideral a partir du temps
853 legal et de la date
854GMST_at_0h_UT(JMA date)
855 Cette fonction calcule le temps sideral moyen a greenwich a 0h UT
856--
857*/
858
859/* Nouvelle-Fonction */
860HMS TLegtoTSid(JMA date, HMS TZ)
861
862/* Cette fonction donne le temps sideral a partir du temps legal */
863/* et la date */
864{
865HMS Orgh,TU,TSid;
866JMA Orgd;
867int off;
868long lj;
869double ts,ratio;
870
871/* Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral */
872StrgtoJMA("1/1/1989",Orgd);
873StrgtoHMS("6:42:30",Orgh);
874
875
876
877/* Nb de jours / Date Origine */
878lj = JMAtoJ(date) - JMAtoJ(Orgd);
879
880/* On calcule l'heure TU et on tient compte du decalage eventuel de + ou - 1 jour */
881off = TLegOffset(date, TZ);
882TU = TZ;
883TU.Heures -= off;
884if (TU.Heures < 0)
885 {
886 lj -= 1;
887 TU.Heures += 24;
888 }
889if (TU.Heures >= 24)
890 {
891 lj += 1;
892 TU.Heures -= 24;
893 }
894
895
896
897ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
898ratio = (ratio+1) / ratio ;
899
900/* Calcul du decalage en heures du temps Sideral par rapport a */
901/* l'origine choisie : ts */
902
903ts = lj * (24. * (ratio - 1) );
904ts += ( TU.Heures * ratio );
905ts += ( ( TU.Minutes / 60. ) * ratio );
906ts += ( (TU.Secondes / 3600. ) * ratio );
907
908ts += HMStoH(Orgh);
909
910/* On tient compte de l'offset du temps solaire moyen */
911ts += TSolMOff;
912
913TSid = HtoHMS(ts);
914TSid.Heures = TSid.Heures % 24;
915if (TSid.Heures < 0) TSid.Heures += 24;
916
917return(TSid);
918}
919
920/*!
921 \ingroup NTools
922 \brief Cette fonction donne le temps sideral moyen a greenwich a 0h UT
923*/
924/* Nouvelle-Fonction */
925HMS GMST_at_0h_UT (JMA date)
926
927/* Cette fonction donne le temps sideral moyen a greenwich a 0h UT */
928/* CMV 5/11/93 */
929{
930HMS Orgh, TSid;
931JMA Orgd;
932long lj, ejs;
933double js, hs, hs0;
934
935/* J H ' " sont les vraies valeurs indiscutables (cf metre etalon etc..) */
936/* Annee Solaire = 365 J 5H 48' 45.2" =~ 365.2421898148 J */
937/* Annee Siderale = 365 J 6H 9' 9.8" =~ 365.2563634259 J */
938/* Le 1er Janvier 1994 0H TU Il sera 6h 41' 40.4305" GMT_Sideral */
939StrgtoJMA("1/1/1994",Orgd);
940StrgtoHMS("6:41:40.4305",Orgh);
941hs0 = HMStoH(Orgh);
942
943/* Nb de jours ecoules depuis la Date Origine */
944lj = JMAtoJ(date) - JMAtoJ(Orgd);
945/* printf("nombre de jours ecoules depuis 1/1/94 %d\n",lj); */
946
947/* Nb de jours sideraux depuis la Date Origine */
948js = (double) lj * 366.2421898148 / 365.2421898148;
949/* Nb d'heures siderales depuis Date Origine (modulo un jour) */
950ejs = (int) js;
951hs = js - (double) ejs;
952hs *= 24.;
953hs += hs0;
954
955TSid = HtoHMS(hs);
956/* printf("nombre d'heures siderales depuis la reference (modulo un jour) %d %d %f\n"
957 ,TSid.Heures,TSid.Minutes,TSid.Secondes); */
958
959return(TSid);
960}
961
962/*
963++
964HMS TUtoTSid(JMA date, HMS TU)
965 Cette fonction calcule le temps sideral GMT a partir du temps
966 universel et de la date GMT.
967int TSidtoTU(JMA date, HMS TS, HMS *TU1, HMS *TU2)
968 Cette fonction calcule les temps universels a partir du temps
969 sideral GMT et de la date GMT. Selon la valeur du TS, il peut y avoir
970 une ou deux possibilites pour le TU (return code).
971--
972*/
973/*!
974 \ingroup NTools
975 Cette fonction calcule le temps sideral GMT a partir du temps
976 universel et de la date GMT.
977 \verbatim
978 Temps sideral
979 Jour Sideral = 86400 Sec. Sid. ( = 24 H Sid. )
980 Annee Solaire = 365 J 5H 48' 46" =~ 365.2422 J
981 Annee Solaire = 365.2422 Jours Solaire Moyen = 366.2422 Jours Sideraux
982 Jour Sol. Moyem = 24 H Sol. = 24 H Sid. * (366.2422 / 365.2422)
983 Jour Solaire Moyen = 86636.555359 Sec. Sid. = 24 H 3' 56.555359"
984 Heure Solaire Moyen = 3609.85647 Sec. Sid.
985 Sec. Sol. = 1.0027379 Sec. Sid.
986 Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral
987 \endverbatim
988*/
989/* Nouvelle-Fonction */
990HMS TUtoTSid(JMA date, HMS TU)
991
992/* Cette fonction donne le temps sideral GMT a partir du temps universel */
993/* et la date GMT */
994{
995HMS Orgh,TSid;
996JMA Orgd;
997long lj;
998double ts,ratio;
999
1000/* Le 1er Janvier 1989 0H TU Il etait 6H 42' 30" GMT_Sideral */
1001StrgtoJMA("1/1/1989",Orgd);
1002StrgtoHMS("6:42:30",Orgh);
1003
1004/* Nb de jours / Date Origine */
1005lj = JMAtoJ(date) - JMAtoJ(Orgd);
1006
1007ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
1008ratio = (ratio+1) / ratio ;
1009
1010/* Calcul du decalage en heures du temps Sideral par rapport a */
1011/* l'origine choisie : ts */
1012
1013ts = lj * (24. * (ratio - 1) );
1014ts += ( TU.Heures * ratio );
1015ts += ( ( TU.Minutes / 60. ) * ratio );
1016ts += ( (TU.Secondes / 3600. ) * ratio );
1017
1018ts += HMStoH(Orgh);
1019
1020TSid = HtoHMS(ts);
1021TSid.Heures = TSid.Heures % 24;
1022if (TSid.Heures < 0) TSid.Heures += 24;
1023
1024return(TSid);
1025}
1026
1027/*!
1028 \ingroup NTools
1029 Cette fonction calcule les temps universels a partir du temps
1030 sideral GMT et de la date GMT. Selon la valeur du TS, il peut y avoir
1031 une ou deux possibilites pour le TU (return code).
1032*/
1033/* Nouvelle-Fonction */
1034int TSidtoTU(JMA date, HMS TS, HMS *TU1, HMS *TU2)
1035
1036/* Cette fonction donne les temps universels a partir du temps sideral GMT */
1037/* et la date GMT */
1038{
1039int rc = 0;
1040HMS Orgh,T0;
1041double ratio,delt,deltt,jsecsid;
1042char strd[16],strh[16];
1043/* char strh1[16]; */
1044
1045TU1->Heures = TU2->Heures = -1;
1046TU1->Minutes = TU2->Minutes = 0;
1047TU1->Secondes = TU2->Secondes = 0.;
1048
1049ratio = ((365.*24.) + 5. + (48. / 60.) + (46. / 3600.)) / 24.;
1050ratio = (ratio / (ratio+1));
1051jsecsid = 86400./ratio;
1052
1053/* temps sideral pour la date a 0h TU */
1054StrgtoHMS("00:00:00",T0);
1055Orgh = TUtoTSid(date,T0);
1056/* JMAtoStrg(date,strd); HMStoStrg(T0,strh); HMStoStrg(Orgh,strh1);
1057printf("... date=%s tu=%s -> org_ts=%s\n",strd,strh,strh1); */
1058
1059/* difference de temps sideral / a 0h TU */
1060delt = HMStoSec(TS) - HMStoSec(Orgh);
1061/* printf("... ts=%f org_ts=%f en sec -> delt=%f (jsecsid=%g)\n"
1062 ,HMStoSec(TS),HMStoSec(Orgh),delt,jsecsid); */
1063
1064if(fabs(delt)<1.e-10) delt=0.;
1065if(delt<0.) delt += 86400.;
1066if( fabs(delt-86400.)<1.e-10 ) delt = 86400. - 1.e-10;
1067if(delt<0. || delt>=86400.+1.e-10) {
1068 HMStoStrg(TS,strh);
1069 JMAtoStrg(date,strd);
1070 printf("*** BUG *** TSidtoTU_erreur: delt=%g<0. (d=%s,ts=%s) *******\n"
1071 ,delt,strd,strh);
1072 return(0);
1073}
1074
1075/* difference de temps / a 0h TU 1ere solution */
1076/* printf("... delt=%f en sec sid",delt); */
1077deltt = delt*ratio;
1078*TU1 = SectoHMS(deltt);
1079*TU2 = *TU1;
1080rc++;
1081/* HMStoStrg((*TU1),strh1);
1082printf("... deltt=%f en sec -> TU1=%s\n",deltt,strh1); */
1083
1084/* Y a t-il une seconde solution ? */
1085if(delt>=jsecsid-86400.-1.e-10) return(rc);
1086delt += 86400.;
1087deltt = delt*ratio;
1088*TU2 = SectoHMS(deltt);
1089/* HMStoStrg((*TU2),strh1);
1090printf("... deltt=%f en sec -> TU2=%s\n",deltt,strh1); */
1091rc++;
1092
1093return (rc);
1094}
1095
1096/*!
1097 \ingroup NTools
1098 Fonction d'initialisation de conversion de temps sideral et legal
1099 pour la ESO-Silla "SetTSolMOff() , SetTLegOff()".
1100 \verbatim
1101 Longitude = 70 deg 43.8 min ouest
1102 Latitude = 29 deg 15.4 min Sud
1103 T Sol. Moyen - TU = -4.715333 Heures
1104 TLegal-TU : -4 Heures de Mars a Octobre, -3 Heures sinon
1105 Changement le 1er dimanche >= 8/03 8/10 a midi (12:00:00)
1106 \endverbatim
1107*/
1108/* Fonction d'initialisation de calcul de temps sideral pour la Silla */
1109void TSidSetupLaSilla()
1110{
1111SetTSolMOff((double)(-4.715333),"La Silla (Chili)");
1112if (SetTLegOff("C -3 87/3 -4 87/10 -3","12:00:00") != 0)
1113 printf(" TSidSetupLaSilla / Erreur SetTLegOff \n");
1114/* Position de l'observatoire */
1115/* SetObsPos("La Silla (Chili)","O 70:43:48","S 29:15:24",2347); */
1116return;
1117}
1118
1119
1120
1121/*!
1122 \ingroup NTools
1123 Calcul du jour Julien pour une date TU.
1124 Uniquement valable a partir du 15/10/1582 00:00:00.
1125
1126*/
1127double ToJulianDay(JMA dateTU, HMS hmsTU)
1128/* Cf Fundamental astronomie, Springer Verlag 2sd ed. cmv 4/12/98 */
1129{
1130double j_dat_0_ut;
1131long int f,g,a;
1132f = (dateTU.Mois>=3) ? dateTU.Annee: dateTU.Annee-1;
1133g = (dateTU.Mois>=3) ? dateTU.Mois: dateTU.Mois+12;
1134a = 2 - (int)((double)f/100.) + (int)((double)f/400.);
1135/* Julian date at 0h UT */
1136j_dat_0_ut = (int)(365.25*(double)f)+(int)(30.6001*(double)(g+1))+dateTU.Jour+a+1720994.5;
1137return j_dat_0_ut + HMStoH(hmsTU)/24.;
1138}
1139
1140/*!
1141 \ingroup NTools
1142 Calcul de la date date et l'heure TU a partir d'un jour Julien.
1143 Retourne 0 si succes.
1144*/
1145int FromJulianDay(double JD,JMA* dateTU, HMS* hmsTU)
1146/* Cf Fundamental astronomie, Springer Verlag 2sd ed. cmv 4/12/98 */
1147{
1148double jd,i,f,a,x,b,c,d,e,h;
1149if(JD<0.) return 1;
1150
1151i = JD - (int)(JD);
1152if(i<0.5) jd = (int)(JD)-0.5; else jd = (int)(JD)+0.5;
1153
1154i = (int)(jd+0.5);
1155f = jd+0.5 - i;
1156if(i<2299161.0) a = i;
1157else {x = (int)((i-1867216.25)/36524.25); a = i+1.+x-(int)(x/4.);}
1158b = a+1524.;
1159c = (int)((b-122.1)/365.25);
1160d = (int)(365.25*c);
1161e = (int)((b-d)/30.6001);
1162
1163x = b-d-(int)(30.6001*e)+f;
1164dateTU->Jour = (int)(x);
1165
1166if(e<13.5) dateTU->Mois = (int)(e-1.); else dateTU->Mois = (int)(e-13.);
1167
1168if(dateTU->Mois>2.5) dateTU->Annee = (int)(c-4716.); else dateTU->Annee = (int)(c-4715.);
1169
1170hmsTU->Heures = hmsTU->Minutes = 0; hmsTU->Secondes = 0.;
1171h = (JD-ToJulianDay(*dateTU,*hmsTU)) * 24.;
1172*hmsTU = HtoHMS(h);
1173
1174return 0;
1175}
1176
1177
1178/*!
1179 \ingroup NTools
1180 Cette fonction renvoie la valeur decimale en heures
1181 d'un angle specifie sous forme de [-][+]dd:mm:ss.
1182*/
1183double StrgtoDegDec(char *strg)
1184/* cmv 4/12/98 */
1185{
1186int dd,mm;
1187float ss;
1188char sgn;
1189double deg;
1190
1191dd = mm = 0;
1192ss = 0.;
1193sgn = *strg;
1194if (isdigit(sgn))
1195 sscanf(strg,"%d:%d:%f",&dd,&mm,&ss);
1196else
1197 sscanf(strg+1,"%d:%d:%f",&dd,&mm,&ss);
1198deg = (double)(dd) + (double)(mm)/60. + (double)(ss)/3600.;
1199if (sgn == '-') deg = (-deg);
1200return(deg);
1201}
1202
1203/*!
1204 \ingroup NTools
1205 Cette fonction ecrit une valeur en degre decimal sous
1206 forme de [-]dd:mm:ss.
1207*/
1208
1209char * DegDectoStrg(double deg, char *strg)
1210/* cmv 4/12/98 */
1211{
1212int dd,mm;
1213float ss;
1214char sgn;
1215
1216if (deg < (double)(0.))
1217 { deg = (-deg) ; sgn = '-' ; }
1218else sgn = '+';
1219dd = (int)deg;
1220deg = (deg-(double)(dd)) * (double)60.;
1221mm = (int)deg;
1222ss = (deg-(double)(mm)) * (double)60.;
1223if (sgn == '-')
1224 sprintf(strg,"-%d:%d:%f",dd,mm,ss);
1225else
1226 sprintf(strg,"%d:%d:%f",dd,mm,ss);
1227return(strg);
1228}
1229
1230/*!
1231 \ingroup NTools
1232 Valeur de l'eccentricite de l'orbite terrestre
1233 a la date TU ``dateTU''.
1234 Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10
1235*/
1236double EccEarth(JMA dateTU)
1237/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10. cmv 9/12/98 */
1238{
1239double JD,T;
1240HMS hmsTU;
1241hmsTU.Heures = 12; hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
1242JD = ToJulianDay(dateTU,hmsTU);
1243/* T en siecles juliens depuis 31/12/1899 a 12h TU --> JD=2415020. */
1244T = (JD-2415020.)/36525;
1245return(0.0167498 - 0.00004258*T - 0.000000137*T*T);
1246}
1247
1248/*!
1249 \ingroup NTools
1250 Valeur de l'obliquite de l'orbite terrestre
1251 a la date TU ``dateTU'' (en degres decimaux).
1252*/
1253double ObliqEarth(JMA dateTU)
1254/* Cf Fundamental astronomie, Springer Verlag 2sd ed. cmv 9/12/98 */
1255/* le 1/1/1900 a 0h00 TU --> jd = 2415020.5 */
1256{
1257double jd;
1258HMS hmsTU;
1259hmsTU.Heures = hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
1260jd = ToJulianDay(dateTU,hmsTU) - 2415020.5;
1261return(23.452294 - 0.00013 *jd/365.25);
1262}
1263
1264/*!
1265 \ingroup NTools
1266 Retourne la Longitude Ecliptique du perihelie de
1267 l'orbite terrestre a la date TU ``dateTU'' (en degres decimaux).
1268*/
1269double LongEcPerihelie(JMA dateTU)
1270/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10. cmv 9/12/98 */
1271{
1272double JD,T;
1273HMS hmsTU;
1274hmsTU.Heures = 12; hmsTU.Minutes = 0; hmsTU.Secondes = 0.;
1275JD = ToJulianDay(dateTU,hmsTU);
1276/* T en siecles juliens depuis 31/12/1899 a 12h TU --> JD=2415020. */
1277T = (JD-2415020.)/36525;
1278/* l = 101d 13' 07.15" + 6171.77" *T + 1.823" *T^2 */
1279return(101.218652778 + 1.71438055556*T + 0.000506388889*T*T);
1280}
1281
1282/*!
1283 \ingroup NTools
1284 Renvoie les coordonnees ecliptiques \b (l,b) a partir de
1285 coordonnees equatoriales \b (a,d) a la date TU \b dateTU.
1286 La date permet de corriger la variation annuelle
1287 de l'obliquite terrestre.
1288*/
1289void EquatToEclip(double a,double d,double* l,double *b,JMA dateTU)
1290/* Cf Fundamental astronomie, Springer Verlag 2sd ed p477 table E10. cmv 9/12/98 */
1291/* l=[0,360[, b=[-90,90] */
1292{
1293double e,sinb,cosb,sinl,cosl;
1294
1295e = ObliqEarth(dateTU)*DegenRad;
1296a *= DegenRad; d *= DegenRad;
1297
1298sinb = sin(d)*cos(e)-cos(d)*sin(e)*sin(a);
1299if(sinb>1.) sinb=1.; if(sinb<-1.) sinb=-1.;
1300*b = asin(sinb);
1301cosb = cos(*b);
1302
1303*l = 0.;
1304if(cosb!=0.) {
1305 sinl = (sin(d)*sin(e)+cos(d)*cos(e)*sin(a))/cosb;
1306 cosl = cos(d)*cos(a)/cosb;
1307 if(cosl>1.) cosl=1.; if(cosl<-1.) cosl=-1.;
1308 *l = acos(cosl);
1309 if(sinl<0.) *l += M_PI;
1310 if(*l>2.*M_PI) *l -= 2.*M_PI;
1311}
1312
1313*b /= DegenRad;
1314*l /= DegenRad;
1315}
Note: See TracBrowser for help on using the repository browser.