source: LMDZ6/trunk/libf/phylmd/rrtm/dates.F90 @ 5450

Last change on this file since 5450 was 5390, checked in by yann meurdesoif, 3 weeks ago
  • Remove UTF8 character that inihibit fortran parsing with GPU morphosis
  • Add missing END SUBROUTINE instead of simple END, that inhibit correct parsing with regulat expression parser (quick and dirty parsing)

YM

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 35.4 KB
Line 
1subroutine dates_demo
2! --------------------------------------------------------------
3!
4! Conseils a l'utilisateur:
5!
6! 1. VOUS COMPILEZ LES ENTIERS EN 32 BITS:
7! Utilisez alors les routines
8! - ecartds: Ecart en secondes entre deux dates.
9! - ecartdj: Ecart en jours entre deux dates.
10! - dapluss: Date dans n secondes.
11! - daplusj: Date dans n jours.
12! - qqmmaa: Conversion d'un entier type AAAAQQMM vers une date en clair.
13! - ijoursem: Jour de la semaine de la date d'entree.
14! - quant: quantieme de l'annee d'une date donnee.
15! Ces routines sont compatibles avec des entiers 32 bits.
16! En effet elles appelent les routines citees ci-dessous, mais avec
17! les parametres subsequents assurant que seuls des entiers
18! representables en 32 bits y soient utilises.
19!
20! 2. VOUS COMPILEZ LES ENTIERS EN 64 BITS:
21! Vous pouvez alors utiliser toutes les routines ci-dessus
22! plus les suivantes, qui traitent des formats de dates
23! en entree/sortie en JOURS, HEURES, MINUTES ou SECONDES:
24! - ecartd: Ecart entre deux dates.
25! - gregod: Conversion Date > Ecart par rapport a une date fixe.
26! - gregoi: Conversion Ecart par rapport a une date fixe > Date.
27! - daplus: Quelle sera la date dans n jours (ou heures, etc...)?
28! - amqhms_vers_dj: Conversion date grégorienne (en 5 entiers et un réel) > date julienne.
29! - dj_vers_amqhms: Conversion date julienne > date grégorienne (en 5 entiers et un réel).
30! - amqhmsree_vers_dj: Conversion date grégorienne (en un seul réel) > date julienne.
31! - dj_vers_amqhmsree: Conversion date julienne > date grégorienne (en un seul réel).
32!
33! --------------------------------------------------------------
34!
35! Définition des dates employées ci-dessous:
36!
37! Date julienne DJ:
38!       Elle est composée d'un réel.
39!       R1: Ce réel croît de 1 tous les jours,
40!               et vaut 2451545.0 le 1er janvier 2000 à 12 UTC.
41!
42! Date grégorienne "en clair" AMQHMS:
43!       Elle est composée de 5 entiers et d'un réel.
44!       E1: Année (4 chiffres!)
45!       E2: Mois
46!       E3: Jour
47!       E4: Heure
48!       E5: Minute
49!       R1: Seconde
50! --------------------------------------------------------------
51
52
53IMPLICIT NONE
54end subroutine dates_demo
55subroutine date_plus_ech(kan,kmo,kqu,psssss,pstati,cdtit)
56! --------------------------------------------------------------
57! Ecriture en clair d'une date de type BASE 2000.01.15 00:00 +72H VALID 2000.01.18 15:00.
58! --------------------------------------------------------------
59! Sujet:
60! Arguments explicites:
61! Arguments implicites:
62! Methode:
63! Externes:
64! Auteur:   2000-09, J.M. Piriou.
65! Modifications:
66! --------------------------------------------------------------
67! En entree:
68! kan,kmo,kqu,psssss,pstati
69! En sortie:
70! cdtit
71! --------------------------------------------------------------
72
73
74IMPLICIT NONE
75INTEGER(KIND=4) :: kan,kmo,kqu,ihe,imi,imiv,ihev,iquv,imov,ianv,ilze
76REAL(KIND=8) :: psssss,pstati
77REAL(KIND=8) :: zs
78REAL(KIND=8) :: zsssss,zdj,zsv
79REAL(KIND=8) :: zech
80character*200 clzue,clze,clech
81character *(*) cdtit
82!
83!-------------------------------------------------
84! Date de validité.
85!-------------------------------------------------
86!
87zs=0.
88zsssss=psssss/3600.
89ihe=int(zsssss) ! heure de la base.
90zsssss=(zsssss-real(ihe))*60.
91imi=int(zsssss) ! minute de la base.
92zsssss=zsssss-real(imi)
93call amqhms_vers_dj(kan,kmo,kqu,ihe,imi,zs,zdj)
94zdj=zdj+pstati/86400. ! date julienne de validité.
95call dj_vers_amqhms(zdj,ianv,imov,iquv,ihev,imiv,zsv) ! date grégorienne de validité.
96if(pstati < 3600.) then
97!
98!-------------------------------------------------
99! Echéance en minutes.
100!-------------------------------------------------
101!
102        zech=pstati/60. ; clzue='mn'
103elseif(pstati < 259200.) then
104!
105!-------------------------------------------------
106! Echéance en heures.
107!-------------------------------------------------
108!
109        zech=pstati/3600. ; clzue='h'
110else
111!
112!-------------------------------------------------
113! Echéance en jours.
114!-------------------------------------------------
115!
116        zech=pstati/86400. ; clzue='j'
117endif
118!
119! Affichage de l'echeance avec deux chiffres apres la virgule.
120!
121write(clze,fmt='(f9.2)') zech
122!
123! Si l'echeance est voisine d'un entier a mieux que 10**-2 pres,
124! on l'affiche au format entier.
125!
126if(clze(len_trim(clze)-2:len_trim(clze)) == '.00') then
127        clze=clze(1:len_trim(clze)-3)
128endif
129clze=adjustl(clze)
130ilze=len_trim(clze)
131clech=clze(1:ilze)//clzue
132!
133!-------------------------------------------------
134! Titre 3, de type
135! BASE 2000.01.15 00:00 +72H VALID 2000.01.18 15:00.
136!-------------------------------------------------
137!
138if(imi == 0 .and. imiv == 0) then
139!
140!-------------------------------------------------
141! Les minutes de base et validité sont nulles.
142! On ne les affiche pas.
143!-------------------------------------------------
144!
145        write(cdtit,fmt='(a,i2,a,i2.2,a,i4.4,a,i2.2,3a,i2,a,i2.2,a,i4.4,a,i2.2,a)')&
146        &'BASE ',kqu,'.',kmo,'.',kan,' ',ihe,'h UTC + ',clech(1:len_trim(clech))&
147        &,', VALID ',iquv,'.',imov,'.',ianv,' ',ihev,'h UTC'
148else
149!
150!-------------------------------------------------
151! Les minutes de base ou validité sont non nulles.
152! On les affiche.
153!-------------------------------------------------
154!
155        write(cdtit,fmt='(a,i2,a,i2.2,a,i4.4,a,i2.2,a,i2.2,3a,i2,a,i2.2,a,i4.4,a,i2.2,a,i2.2,a)')&
156        &'BASE ',kqu,'.',kmo,'.',kan,' ',ihe,':',imi,' UTC + ',clech(1:len_trim(clech))&
157        &,' VALID ',iquv,'.',imov,'.',ianv,' ',ihev,':',imiv,' UTC'
158endif
159end subroutine date_plus_ech
160
161subroutine datc(kaaaa,kmm,kqq,khh,kmi,kss,kjs,cdjs,cddt)
162! --------------------------------------------------------------
163! **** *datc* Date courante machine.
164! --------------------------------------------------------------
165! Sujet:
166! ------
167! Arguments explicites:
168! ---------------------
169! Arguments implicites:
170! ---------------------
171! Methode:
172! --------
173! Externes:
174! ---------
175! Auteur:   95-05, J.M. Piriou.
176! -------
177! Modifications:
178! --------------------------------------------------------------
179! En entree:
180! En sortie:
181! kaaaa      annee.
182! kmm      mois.
183! kqq      quantieme.
184! khh      heure.
185! kmi      minute.
186! kss      seconde.
187! kjs      jour de la semaine (0: dimanche, 6 samedi).
188! cdjs      jour de la semaine sur 3 caracteres (Dim, Lun, etc...).
189! cddt      date totale (19950301-Mer-16:56:32).
190! --------------------------------------------------------------
191
192
193IMPLICIT NONE
194INTEGER(KIND=4) :: idatat(8)
195INTEGER(KIND=4) :: kjs
196INTEGER(KIND=4) :: kss
197INTEGER(KIND=4) :: kmi
198INTEGER(KIND=4) :: khh
199INTEGER(KIND=4) :: kqq
200INTEGER(KIND=4) :: kmm
201INTEGER(KIND=4) :: kaaaa
202INTEGER(KIND=4) :: iaaaammqq
203INTEGER(KIND=4) :: ijoursem
204REAL(KIND=8) :: zs
205character*200 clgol1,clgol2,clgol3
206character*3 cdjs
207character*(*) cddt
208character*3 cljour(0:6)
209data cljour/'Dim','Lun','Mar','Mer','Jeu','Ven','Sam'/
210!
211!-------------------------------------------------
212! Date courante à la f90.
213!-------------------------------------------------
214!
215clgol1=' '
216clgol2=' '
217clgol3=' '
218call date_and_time(clgol1,clgol2,clgol3,idatat)
219!
220!-------------------------------------------------
221! clgol1 est du type "AAAAMMQQ".
222!-------------------------------------------------
223!
224read(clgol1,fmt='(i4,2i2)') kaaaa,kmm,kqq
225!
226!-------------------------------------------------
227! clgol2 est du type "HHMMSS.SSS".
228!-------------------------------------------------
229!
230read(clgol2,fmt='(2i2)') khh,kmi
231read(clgol2(5:),fmt=*) zs
232kss=nint(zs)
233read(clgol1,fmt='(i8)') iaaaammqq
234!
235!-------------------------------------------------
236! Jour de la semaine.
237!-------------------------------------------------
238!
239kjs=ijoursem(iaaaammqq)
240cdjs=cljour(kjs)
241!
242!-------------------------------------------------
243! Date totale.
244!-------------------------------------------------
245!
246write(cddt,fmt='(i4.4,a,2(i2.2,a),2a,i2.2,a,i2.2,a,i2.2)') &
247&kaaaa,'_',kmm,'_',kqq,'_',cdjs,'_',khh,':',kmi,':',kss
248end subroutine datc
249
250subroutine amqhms_vers_dj(kaaaa,kmm,kqq,khh,kmn,ps,pdj)
251! --------------------------------------------------------------------------
252! **** *amqhms_vers_dj*
253! --------------------------------------------------------------------------
254! Auteur:
255! -------
256! 1999-08-17, J.M. Piriou.
257!
258! Modifications:
259! --------------
260!
261! --------------------------------------------------------------------------
262! En entree:
263! kaaaa année (4 chiffres!)
264! kmm   mois
265! kqq   quantième du mois
266! khh   heure
267! kmn   minute
268! ps    seconde
269! En sortie:
270! pdj date julienne associée à la date grégorienne UTC d'entrée
271! --------------------------------------------------------------------------
272
273
274IMPLICIT NONE
275INTEGER(KIND=4) :: IDATE1
276INTEGER(KIND=4) :: IDATE2
277INTEGER(KIND=4) :: IECART
278INTEGER(KIND=4) :: KAAAA
279INTEGER(KIND=4) :: KHH
280INTEGER(KIND=4) :: KMM
281INTEGER(KIND=4) :: KMN
282INTEGER(KIND=4) :: KQQ
283REAL(KIND=8) :: PDJ
284REAL(KIND=8) :: PS
285
286idate1=20000101
287idate2=kaaaa*10000+kmm*100+kqq
288!
289!-------------------------------------------------
290! Nombre de jours écoulés entre la date
291! d'entrée à 0h UTC et le 1er janvier 2000 à 0h UTC.
292!-------------------------------------------------
293!
294call ecartdj(idate1,idate2,iecart)
295!
296!-------------------------------------------------
297! Date julienne.
298!-------------------------------------------------
299!
300pdj=2451545.0- 0.5 +real(iecart)+real(khh)/24. &
301& +real(kmn)/1440.+ps/86400.
302end subroutine amqhms_vers_dj
303
304subroutine daplus(kdat1,kopt,kdelt,kdat2)
305! --------------------------------------------------------------------------
306! **** *DAPLUS* Quelle sera la date dans n jours (ou heures, etc...)?
307! --------------------------------------------------------------------------
308! Auteur:
309! -------
310! 94-10-31, J.M. Piriou.
311!
312! Modifications:
313! --------------
314!
315! --------------------------------------------------------------------------
316! En entree:
317! kdat1
318! kopt option de precision sur les dates:
319! 1 : au jour pres
320! 2 : a l'heure pres
321! 3 : a la minute pres
322! 4 : a la seconde pres
323! - si kopt=1 : kdat au format AAAAMMQQ
324! - si kopt=2 : kdat au format AAAAMMQQHH
325! - si kopt=3 : kdat au format AAAAMMQQHHMM
326! - si kopt=4 : kdat au format AAAAMMQQHHMMSS
327! (cf. GREGOD).
328! kdelt duree a ajouter a kdat1, unite: celle imposee par kopt.
329! En sortie:
330! kdat2 date finale.
331!
332! --------------------------------------------------------------------------
333! Exemple: call DAPLUS(19940503,1,456,ires) fournira
334! dans ires la date au format AAAAMMQQ situee 456 jours apres
335! le 3 mai 1994.
336! --------------------------------------------------------------------------
337! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
338! ATTENTION A LA PRECISION:
339! 1. Vous compilez les entiers sur 32 bits:
340! Vous devez alors vous limiter a kopt <= 2.
341! 2. Vous compilez les entiers sur 64 bits:
342! Vous pouvez utiliser toutes les valeurs de kopt.
343! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
344
345
346IMPLICIT NONE
347INTEGER(KIND=4) :: IGRE
348INTEGER(KIND=4) :: KDAT1
349INTEGER(KIND=4) :: KDAT2
350INTEGER(KIND=4) :: KDELT
351INTEGER(KIND=4) :: KOPT
352call gregod(kdat1,kopt,igre)
353igre=igre+kdelt
354call gregoi(igre,kopt,kdat2)
355end subroutine daplus
356
357subroutine daplusj(k1,kec,k2)
358! --------------------------------------------------------------
359! **** *daplusj* Date dans n jours.
360! --------------------------------------------------------------
361! Sujet:
362! Arguments explicites:
363! Arguments implicites:
364! Methode:
365! Externes:
366! Auteur:   97-11, J.M. Piriou.
367! Modifications:
368! --------------------------------------------------------------
369! En entree:
370! k1 date de depart au format AAAAMMQQ.
371! kec nombre de jours ecoules.
372! En sortie:
373! k2 date d'arrivee au format AAAAMMQQ.
374! --------------------------------------------------------------
375! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
376! PRECISION:
377! Cette routine est utilisable avec des entiers 32 bits ou 64 bits.
378! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
379!
380! -------------------------------------------------
381! Date d'arrivee au jour pres.
382! -------------------------------------------------
383!
384
385
386IMPLICIT NONE
387INTEGER(KIND=4) :: K1
388INTEGER(KIND=4) :: K2
389INTEGER(KIND=4) :: KEC
390call daplus(k1,1,kec,k2)
391end subroutine daplusj
392
393subroutine dapluss(cd1,kec,cd2)
394! --------------------------------------------------------------
395! **** *dapluss* Date dans n secondes.
396! --------------------------------------------------------------
397! Sujet:
398! Arguments explicites:
399! Arguments implicites:
400! Methode:
401! Externes:
402! Auteur:   97-11, J.M. Piriou.
403! Modifications:
404! --------------------------------------------------------------
405! En entree:
406! cd1 date de depart au format 'AAAAMMQQHHNNSS'.
407! kec nombre de secondes ecoulees.
408! En sortie:
409! cd2 date d'arrivee au format 'AAAAMMQQHHNNSS'.
410! --------------------------------------------------------------
411! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
412! ATTENTION A LA PRECISION:
413! Cette routine est utilisable avec des entiers 32 bits,
414! si l'ecart entre les deux dates est inferieur a 2**31 secondes,
415! soit 68 ans!...
416!
417! Au-dela de cette duree, les entiers doivent etre 64 bits.
418! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
419
420
421IMPLICIT NONE
422INTEGER(KIND=4) :: IAMQ1
423INTEGER(KIND=4) :: IAMQ2
424INTEGER(KIND=4) :: IDELTA
425INTEGER(KIND=4) :: IECJOURS
426INTEGER(KIND=4) :: IH1
427INTEGER(KIND=4) :: IH2
428INTEGER(KIND=4) :: IM1
429INTEGER(KIND=4) :: IM2
430INTEGER(KIND=4) :: IRESTE
431INTEGER(KIND=4) :: IS1
432INTEGER(KIND=4) :: IS2
433INTEGER(KIND=4) :: ISEC
434INTEGER(KIND=4) :: KEC
435character*(*) cd1,cd2
436!
437! -------------------------------------------------
438! On lit les dates sur des entiers.
439! -------------------------------------------------
440!
441read(cd1,fmt='(i8,3i2)') iamq1,ih1,im1,is1
442!
443! -------------------------------------------------
444! Calculs d'ecarts et de leur partition
445! en multiples de 86400 et sous-multiples.
446! -------------------------------------------------
447!
448isec=ih1*3600+im1*60+is1 ! nombre de secondes ecoulees depuis cd10h.
449idelta=kec+isec ! nombre de secondes entre cd10h et cd2.
450ireste=modulo(idelta,86400) ! nombre de secondes entre cd20h et cd2.
451iecjours=(idelta-ireste)/86400 ! nombre de jours entre cd10h et cd20h.
452!
453! -------------------------------------------------
454! Date d'arrivee au jour pres.
455! -------------------------------------------------
456!
457call daplus(iamq1,1,iecjours,iamq2)
458!
459! -------------------------------------------------
460! Date finale a la seconde pres.
461! -------------------------------------------------
462!
463ih2=ireste/3600
464ireste=ireste-3600*ih2
465im2=ireste/60
466ireste=ireste-60*im2
467is2=ireste
468write(cd2,fmt='(i8,3i2.2)') iamq2,ih2,im2,is2
469end subroutine dapluss
470
471subroutine dj_vers_amqhms(pdj,kaaaa,kmm,kqq,khh,kmn,ps)
472! --------------------------------------------------------------------------
473! **** *dj_vers_amqhms*
474! --------------------------------------------------------------------------
475! Auteur:
476! -------
477! 1999-08-17, J.M. Piriou.
478!
479! Modifications:
480! --------------
481!
482! --------------------------------------------------------------------------
483! En entree:
484! pdj date julienne associée à la date grégorienne UTC d'entrée
485! En sortie:
486! kaaaa année (4 chiffres!)
487! kmm   mois
488! kqq   quantième du mois
489! khh   heure
490! kmn   minute
491! ps    seconde
492! --------------------------------------------------------------------------
493!
494!-------------------------------------------------
495! Nombre de jours entre le 1er janvier 2000 à 0 UTC
496! et la date julienne courante.
497!-------------------------------------------------
498!
499
500
501IMPLICIT NONE
502INTEGER(KIND=4) :: IDATE1
503INTEGER(KIND=4) :: IDATE2
504INTEGER(KIND=4) :: IECART
505INTEGER(KIND=4) :: KAAAA
506INTEGER(KIND=4) :: KHH
507INTEGER(KIND=4) :: KMM
508INTEGER(KIND=4) :: KMN
509INTEGER(KIND=4) :: KNOUV
510INTEGER(KIND=4) :: KQQ
511REAL(KIND=8) :: PDJ
512REAL(KIND=8) :: PS
513REAL(KIND=8) :: ZECART
514REAL(KIND=8) :: ZFRAC
515zecart=pdj-2451544.5
516!
517!-------------------------------------------------
518! Nombre entier de jours.
519!-------------------------------------------------
520!
521zfrac=modulo(zecart, 1._8 )
522iecart=nint(zecart-zfrac)
523!
524!-------------------------------------------------
525! Date grégorienne associée.
526!-------------------------------------------------
527!
528idate1=20000101
529call daplusj(idate1,iecart,idate2)
530kqq=mod(idate2,100)
531knouv=idate2/100
532kmm=mod(knouv,100)
533kaaaa=knouv/100
534!
535!-------------------------------------------------
536! Calcul de des heure, minute et seconde.
537!-------------------------------------------------
538!
539zfrac=(zecart-real(iecart))*24.
540khh=int(zfrac)
541zfrac=(zfrac-real(khh))*60.
542kmn=int(zfrac)
543ps=(zfrac-real(kmn))*60.
544end subroutine dj_vers_amqhms
545
546subroutine dj_vers_amqhmsree(pdj,pgrer)
547! --------------------------------------------------------------------------
548! **** **
549! --------------------------------------------------------------------------
550! Auteur:
551! -------
552! 2002-11, J.M. Piriou.
553!
554! Modifications:
555! --------------
556!
557! --------------------------------------------------------------------------
558! En entree:
559! pdj date julienne
560! En sortie:
561! pgrer date en clair au format AAAAMMQQ.HHMMSS
562! --------------------------------------------------------------------------
563!
564
565IMPLICIT NONE
566REAL(KIND=8), intent(in) :: PDJ
567REAL(KIND=8), intent(out) :: pgrer
568REAL(KIND=8) :: ZS
569INTEGER(KIND=4) :: iaaaa,imm,iqq,ihh,imn
570!
571!-------------------------------------------------
572! Conversion grégorien julien; cible 5 entiers et un réel.
573!-------------------------------------------------
574!
575call dj_vers_amqhms(pdj,iaaaa,imm,iqq,ihh,imn,zs)
576!
577!-------------------------------------------------
578! On passe de ces 5 entiers et un réel à un seul réel.
579!-------------------------------------------------
580!
581pgrer=real(iaaaa)*10000.+real(imm)*100. &
582& + real(iqq)+real(ihh)/100. &
583& + real(imn)/10000.+zs/1.E+06
584end subroutine dj_vers_amqhmsree
585
586subroutine amqhmsree_vers_dj(pgrer,pdj)
587! --------------------------------------------------------------------------
588! **** **
589! --------------------------------------------------------------------------
590! Auteur:
591! -------
592! 2002-11, J.M. Piriou.
593!
594! Modifications:
595! --------------
596!
597! --------------------------------------------------------------------------
598! En entree:
599! pgrer date en clair au format AAAAMMQQ.HHMMSS
600! En sortie:
601! pdj date julienne associée à la date grégorienne
602! --------------------------------------------------------------------------
603!
604
605IMPLICIT NONE
606REAL(KIND=8), intent(out) :: PDJ
607REAL(KIND=8), intent(in) :: pgrer
608REAL(KIND=8) :: ZS,zloc
609INTEGER(KIND=4) :: iaaaa,imm,iqq,ihh,imn,iloc
610!
611!-------------------------------------------------
612! On passe de cette date grégorienne donnée
613! comme un seul réel à 5 entiers et un réel.
614!-------------------------------------------------
615!
616iloc=int(pgrer)
617iqq=mod(iloc,100)
618iloc=iloc/100
619imm=mod(iloc,100)
620iaaaa=iloc/100
621
622iloc=nint((pgrer-real(int(pgrer)))*1.E+06)
623zs=real(mod(iloc,100))
624iloc=iloc/100
625imn=mod(iloc,100)
626ihh=iloc/100
627!
628!-------------------------------------------------
629! Conversion grégorien julien; cible 5 entiers et un réel.
630!-------------------------------------------------
631!
632call amqhms_vers_dj(iaaaa,imm,iqq,ihh,imn,zs,pdj)
633end subroutine amqhmsree_vers_dj
634
635subroutine ecartd(kdat1,kdat2,kopt,kgre)
636! --------------------------------------------------------------------------
637! **** *ECART* Ecart entre deux dates.
638! --------------------------------------------------------------------------
639! Auteur:
640! -------
641! 97-01-09, J.M. Piriou.
642!
643! Modifications:
644! --------------
645!
646! --------------------------------------------------------------------------
647! En entree: kopt option de precision sur les dates:
648! 1 : au jour pres
649! 2 : a l'heure pres
650! 3 : a la minute pres
651! 4 : a la seconde pres
652! - si kopt=1 : kdat au format AAAAMMQQ
653! - si kopt=2 : kdat au format AAAAMMQQHH
654! - si kopt=3 : kdat au format AAAAMMQQHHMM
655! - si kopt=4 : kdat au format AAAAMMQQHHMMSS
656! kdat1 et kdat2 dates au format ci-dessus.
657! En sortie:
658! - si kopt=1 : kgre nombre de jours    entre kdat1 et kdat2
659! - si kopt=2 : kgre nombre d'heures    entre kdat1 et kdat2
660! - si kopt=3 : kgre nombre de minutes  entre kdat1 et kdat2
661! - si kopt=4 : kgre nombre de secondes entre kdat1 et kdat2
662! --------------------------------------------------------------------------
663! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
664! ATTENTION A LA PRECISION:
665! 1. Vous compilez les entiers sur 32 bits:
666! Vous devez alors vous limiter a kopt <= 2.
667! L'ecart entre les deux dates doit etre inferieur a
668! - 2**31 heures si kopt=2
669! - 2**31 jours si kopt=1
670! 2. Vous compilez les entiers sur 64 bits:
671! Vous pouvez utiliser toutes les valeurs de kopt.
672! L'ecart entre les deux dates doit etre inferieur a
673! - 2**63 secondes si kopt=4
674! - 2**63 minutes si kopt=3
675! - 2**63 heures si kopt=2
676! - 2**63 jours si kopt=1
677! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
678
679
680IMPLICIT NONE
681INTEGER(KIND=4) :: IGRE1
682INTEGER(KIND=4) :: IGRE2
683INTEGER(KIND=4) :: KDAT1
684INTEGER(KIND=4) :: KDAT2
685INTEGER(KIND=4) :: KGRE
686INTEGER(KIND=4) :: KOPT
687call gregod(kdat1,kopt,igre1)
688call gregod(kdat2,kopt,igre2)
689kgre=igre2-igre1
690end subroutine ecartd
691
692subroutine ecartdj(k1,k2,kec)
693! --------------------------------------------------------------
694! **** *ecartdj* Ecart en jours entre deux dates.
695! --------------------------------------------------------------
696! Sujet:
697! Arguments explicites:
698! Arguments implicites:
699! Methode:
700! Externes:
701! Auteur:   97-11, J.M. Piriou.
702! Modifications:
703! --------------------------------------------------------------
704! En entree:
705! k1 date de depart au format AAAAMMQQ.
706! k2 date d'arrivee au format AAAAMMQQ.
707! En sortie:
708! kec: nombre de jours entre les deux dates.
709! --------------------------------------------------------------
710! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
711! ATTENTION A LA PRECISION:
712! Cette routine est utilisable avec des entiers 32 bits,
713! si l'ecart entre les deux dates est inferieur a 2**31 jours,
714! soit 5879489 ans!...
715!
716! Au-dela de cette duree, les entiers doivent etre 64 bits.
717! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
718!
719! -------------------------------------------------
720! Ecart entre les deux dates au jour pres.
721! -------------------------------------------------
722!
723
724
725IMPLICIT NONE
726INTEGER(KIND=4) :: K1
727INTEGER(KIND=4) :: K2
728INTEGER(KIND=4) :: KEC
729call ecartd(k1,k2,1,kec)
730end subroutine ecartdj
731
732subroutine ecartds(cd1,cd2,kec)
733! --------------------------------------------------------------
734! **** *ecartds* Ecart en secondes entre deux dates.
735! --------------------------------------------------------------
736! Sujet:
737! Arguments explicites:
738! Arguments implicites:
739! Methode:
740! Externes:
741! Auteur:   97-11, J.M. Piriou.
742! Modifications:
743! --------------------------------------------------------------
744! En entree:
745! cd1 date de depart au format 'AAAAMMQQHHNNSS'.
746! cd2 date d'arrivee au format 'AAAAMMQQHHNNSS'.
747! En sortie:
748! kec: nombre de secondes entre les deux dates.
749! --------------------------------------------------------------
750! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
751! ATTENTION A LA PRECISION:
752! Cette routine est utilisable avec des entiers 32 bits,
753! si l'ecart entre les deux dates est inferieur a 2**31 secondes,
754! soit 68 ans!...
755!
756! Au-dela de cette duree, les entiers doivent etre 64 bits.
757! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
758
759
760IMPLICIT NONE
761INTEGER(KIND=4) :: IAMQ1
762INTEGER(KIND=4) :: IAMQ2
763INTEGER(KIND=4) :: IH1
764INTEGER(KIND=4) :: IH2
765INTEGER(KIND=4) :: IM1
766INTEGER(KIND=4) :: IM2
767INTEGER(KIND=4) :: IS1
768INTEGER(KIND=4) :: IS2
769INTEGER(KIND=4) :: KEC
770INTEGER(KIND=4) :: KECQ
771character*(*) cd1,cd2
772!
773! -------------------------------------------------
774! On lit les dates sur des entiers.
775! -------------------------------------------------
776!
777read(cd1,fmt='(i8,3i2)') iamq1,ih1,im1,is1
778read(cd2,fmt='(i8,3i2)') iamq2,ih2,im2,is2
779!
780! -------------------------------------------------
781! Ecart entre les deux dates au jour pres.
782! -------------------------------------------------
783!
784call ecartd(iamq1,iamq2,1,kecq)
785!
786! -------------------------------------------------
787! Ecart en secondes.
788! -------------------------------------------------
789!
790kec=kecq*86400+(ih2-ih1)*3600+(im2-im1)*60+is2-is1
791end subroutine ecartds
792
793subroutine gregod(kdat,kopt,kgre)
794! --------------------------------------------------------------------------
795! **** *GREGOD *  - Conversion Date > Ecart par rapport a une date fixe.
796! --------------------------------------------------------------------------
797! Auteur:
798! -------
799! 92-05-27, J.M. Piriou.
800!
801! Modifications:
802! --------------
803!
804! --------------------------------------------------------------------------
805! En entree: kopt option de precision sur les dates:
806! 1 : au jour pres
807! 2 : a l'heure pres
808! 3 : a la minute pres
809! 4 : a la seconde pres
810! - si kopt=1 : kdat au format AAAAMMQQ
811! - si kopt=2 : kdat au format AAAAMMQQHH
812! - si kopt=3 : kdat au format AAAAMMQQHHMM
813! - si kopt=4 : kdat au format AAAAMMQQHHMMSS
814! En sortie:
815! - si kopt=1 : kgre nombre de jours    entre 19000101       et kdat
816! - si kopt=2 : kgre nombre d'heures    entre 1900010100     et kdat
817! - si kopt=3 : kgre nombre de minutes  entre 190001010000   et kdat
818! - si kopt=4 : kgre nombre de secondes entre 19000101000000 et kdat
819! --------------------------------------------------------------------------
820! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
821! ATTENTION A LA PRECISION:
822! 1. Vous compilez les entiers sur 32 bits:
823! Vous devez alors vous limiter a kopt <= 2.
824! 2. Vous compilez les entiers sur 64 bits:
825! Vous pouvez utiliser toutes les valeurs de kopt.
826! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
827
828
829IMPLICIT NONE
830INTEGER(KIND=4) :: idebm(12)
831INTEGER(KIND=4) :: I0
832INTEGER(KIND=4) :: IA100
833INTEGER(KIND=4) :: IA4
834INTEGER(KIND=4) :: IA400
835INTEGER(KIND=4) :: IAAAA
836INTEGER(KIND=4) :: IBISSEXT
837INTEGER(KIND=4) :: ICONV
838INTEGER(KIND=4) :: IFRJOUR
839INTEGER(KIND=4) :: II
840INTEGER(KIND=4) :: II1
841INTEGER(KIND=4) :: IJOURP
842INTEGER(KIND=4) :: IMM
843INTEGER(KIND=4) :: IN
844INTEGER(KIND=4) :: IN1
845INTEGER(KIND=4) :: IN2
846INTEGER(KIND=4) :: IQQ
847INTEGER(KIND=4) :: KDAT
848INTEGER(KIND=4) :: KGRE
849INTEGER(KIND=4) :: KOPT
850data idebm/0,31,59,90,120,151,181,212,243,273,304,334/
851!
852! --------------------------------------------------------------------------
853! **      1. Calcul du nb de jours separant ki2 du 1er janv 1900
854!
855! *       1.1 Extraction des quantieme, mois et annee
856if(kopt == 1) then
857  ! Date de type AAAAMMQQ
858  iconv=1
859  ifrjour=0
860  ii=kdat
861elseif(kopt == 2) then
862  ! Date de type AAAAMMQQHH
863  iconv=24
864  ifrjour=mod(kdat,100)
865  ii=kdat/100
866elseif(kopt == 3) then
867  ! Date de type AAAAMMQQHHMM
868  iconv=1440
869  ifrjour=mod(kdat,100)
870  ii=kdat/100
871  ifrjour=ifrjour+mod(ii,100)*60
872  ii=ii/100
873elseif(kopt == 4) then
874  ! Date de type AAAAMMQQHHMMSS
875  iconv=86400
876  ifrjour=mod(kdat,100)
877  ii=kdat/100
878  ifrjour=ifrjour+mod(ii,100)*60
879  ii=ii/100
880  ifrjour=ifrjour+mod(ii,100)*3600
881  ii=ii/100
882else
883  ! Cas d'entree erronee de l'utilisateur.
884  print*,'GREGODR/ERREUR: argument kopt errone!...'
885  print*,kopt
886  stop 'call abort'
887endif
888iqq=ii-(ii/100)*100
889in=(ii-iqq)/100
890imm=in-(in/100)*100
891iaaaa=(in-imm)/100
892! *       1.2 L'annee est-elle bissextile?
893! Une annee est bissextile ssi elle est
894! (mult de 4 et non mult de 100) ou (mult de 400)
895iaaaa=iaaaa
896ia400=400*(iaaaa/400)
897ia100=100*(iaaaa/100)
898ia4=4*(iaaaa/4)
899if((iaaaa == ia400).or.((iaaaa == ia4).and.(iaaaa /= ia100)))then
900  ibissext=1
901else
902  ibissext=0
903endif
904if ((ibissext == 1).and.(imm > 2)) then
905  ijourp=1
906else
907  ijourp=0
908endif
909! *       1.3 Nombre de jours ecoules depuis le 1er janv
910if(imm > 12) then
911  print*,'GREGODR/ERREUR: mois errone.'
912  print*,imm
913  stop 'call abort'
914endif
915in2=idebm(imm)+ijourp+iqq-1
916! *       1.4 Calcul du nb de jours separant les 1er janvier de ii et 1900
917i0=1900
918in2=in2+365*(iaaaa-i0)+int((iaaaa-1)/4)-int((i0-1)/4)&
919&-int((iaaaa-1)/100)+int((i0-1)/100)&
920&+int((iaaaa-1)/400)-int((i0-1)/400)
921! --------------------------------------------------------------------------
922! **      2. Calcul du nb de jours separant ii1 du 1er janv 1900
923!
924! *       2.1 Extraction des quantieme, mois et annee
925ii1=19000101
926ii=ii1
927iqq=ii-(ii/100)*100
928in=(ii-iqq)/100
929imm=in-(in/100)*100
930iaaaa=(in-imm)/100
931! *       2.2 L'annee est-elle bissextile?
932! Une annee est bissextile ssi elle est
933! (mult de 4 et non mult de 100) ou (mult de 400)
934iaaaa=iaaaa
935ia400=400*(iaaaa/400)
936ia100=100*(iaaaa/100)
937ia4=4*(iaaaa/4)
938if((iaaaa == ia400).or.((iaaaa == ia4).and.(iaaaa /= ia100)))then
939  ibissext=1
940else
941  ibissext=0
942endif
943if ((ibissext == 1).and.(imm > 2)) then
944  ijourp=1
945else
946  ijourp=0
947endif
948! *       2.3 Nombre de jours ecoules depuis le 1er janv
949in1=idebm(imm)+ijourp+iqq-1
950! *       2.4 Calcul du nb de jours separant les 1er janvier de ii et 1900
951i0=1900
952in1=in1+365*(iaaaa-i0)+int((iaaaa-1)/4)-int((i0-1)/4)&
953&-int((iaaaa-1)/100)+int((i0-1)/100)&
954&+int((iaaaa-1)/400)-int((i0-1)/400)
955! --------------------------------------------------------------------------
956! **      3. Difference in2-in1
957kgre=(in2-in1)*iconv+ifrjour
958end subroutine gregod
959
960subroutine gregoi(kgre,kopt,kdat)
961! --------------------------------------------------------------------------
962! **** *GREGOI *  - Conversion Ecart par rapport a une date fixe > Date.
963! --------------------------------------------------------------------------
964! Auteur:
965! -------
966! 92-05-27, J.M. Piriou.
967!
968! Modifications:
969! --------------
970!
971! --------------------------------------------------------------------------
972! En entree: kopt option de precision sur les dates:
973! 1 : au jour pres
974! 2 : a l'heure pres
975! 3 : a la minute pres
976! 4 : a la seconde pres
977! - si kopt=1 : kgre nombre de jours    entre 19000101       et kdat
978! - si kopt=2 : kgre nombre d'heures    entre 1900010100     et kdat
979! - si kopt=3 : kgre nombre de minutes  entre 190001010000   et kdat
980! - si kopt=4 : kgre nombre de secondes entre 19000101000000 et kdat
981! En sortie:
982! - si kopt=1 : kdat au format AAAAMMQQ
983! - si kopt=2 : kdat au format AAAAMMQQHH
984! - si kopt=3 : kdat au format AAAAMMQQHHMM
985! - si kopt=4 : kdat au format AAAAMMQQHHMMSS
986! --------------------------------------------------------------------------
987! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
988! ATTENTION A LA PRECISION:
989! 1. Vous compilez les entiers sur 32 bits:
990! Vous devez alors vous limiter a kopt <= 2.
991! 2. Vous compilez les entiers sur 64 bits:
992! Vous pouvez utiliser toutes les valeurs de kopt.
993! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
994
995
996IMPLICIT NONE
997INTEGER(KIND=4) :: ijours(12)
998INTEGER(KIND=4) :: IA100
999INTEGER(KIND=4) :: IA4
1000INTEGER(KIND=4) :: IA400
1001INTEGER(KIND=4) :: IAAAA
1002INTEGER(KIND=4) :: IBISSEXT
1003INTEGER(KIND=4) :: ICONV
1004INTEGER(KIND=4) :: IDAT
1005INTEGER(KIND=4) :: IEC
1006INTEGER(KIND=4) :: IECI
1007INTEGER(KIND=4) :: IGII2P
1008INTEGER(KIND=4) :: II2P
1009INTEGER(KIND=4) :: IMM
1010INTEGER(KIND=4) :: IMOD
1011INTEGER(KIND=4) :: IQQ
1012INTEGER(KIND=4) :: KDAT
1013INTEGER(KIND=4) :: KGRE
1014INTEGER(KIND=4) :: KOPT
1015REAL(KIND=8) :: ZARRDEC
1016data ijours/31,28,31,30,31,30,31,31,30,31,30,31/
1017! --------------------------------------------------------------------------
1018! **   On determine la date approximative d'arrivee en annees decimales
1019!
1020if(kopt == 1) then
1021  ! Date de type AAAAMMQQ
1022  iconv=1
1023elseif(kopt == 2) then
1024  ! Date de type AAAAMMQQHH
1025  iconv=24
1026elseif(kopt == 3) then
1027  ! Date de type AAAAMMQQHHMM
1028  iconv=1440
1029elseif(kopt == 4) then
1030  ! Date de type AAAAMMQQHHMMSS
1031  iconv=86400
1032else
1033  ! Cas d'entree erronee de l'utilisateur.
1034  print*,'GREGOI/ERREUR: argument kopt errone!...'
1035  print*,kopt
1036  stop 'call abort'
1037endif
1038zarrdec=1900.+(real(kgre)/real(iconv)-5.)/365.2425
1039! --------------------------------------------------------------------------
1040! **   On determine la date en clair ii2p associee a la date decimale
1041!
1042iaaaa=int(zarrdec)
1043zarrdec=12.*(zarrdec-real(iaaaa))
1044imm=int(zarrdec)+1
1045zarrdec=28.*(zarrdec-real(imm-1))
1046iqq=int(zarrdec)+1
1047ii2p=iqq+imm*100+iaaaa*10000
1048! --------------------------------------------------------------------------
1049! **   On calcule le nombre de jours separant 19000101 de ii2p
1050!
1051call gregod(ii2p,1,igii2p)
1052imod=mod(kgre,iconv)
1053if(imod < 0) imod=imod+iconv
1054iec=(kgre-imod)/iconv-igii2p
1055! --------------------------------------------------------------------------
1056! **   On avance de iec jours par rapport a ii2p
1057!
1058! *       L'annee est-elle bissextile?
1059! Une annee est bissextile ssi elle est
1060! (mult de 4 et non mult de 100) ou (mult de 400)
1061iaaaa=iaaaa
1062ia400=400*(iaaaa/400)
1063ia100=100*(iaaaa/100)
1064ia4=4*(iaaaa/4)
1065if((iaaaa == ia400).or.((iaaaa == ia4).and.(iaaaa /= ia100)))then
1066  ibissext=1
1067else
1068  ibissext=0
1069endif
1070! Si oui, 29 jours en fevrier
1071if(ibissext == 1) ijours(2)=29
1072! *       Boucle sur les jours
1073do ieci=1,iec
1074  iqq=iqq+1
1075  if(iqq > ijours(imm)) then
1076    iqq=1
1077    imm=imm+1
1078  endif
1079  if(imm > 12) then
1080    imm=1
1081    iaaaa=iaaaa+1
1082  endif
1083enddo
1084! --------------------------------------------------------------------------
1085! **   On met en forme la date finale
1086!
1087idat=iqq+imm*100+iaaaa*10000
1088if(kopt == 2) then
1089  imod=mod(kgre,iconv)
1090  if(imod < 0) imod=imod+iconv
1091  idat=idat*100+imod
1092elseif(kopt == 3) then
1093  imod=mod(kgre,iconv)
1094  if(imod < 0) imod=imod+iconv
1095  idat=idat*100+imod/60
1096  imod=mod(imod,60)
1097  idat=idat*100+imod
1098elseif(kopt == 4) then
1099  imod=mod(kgre,iconv)
1100  if(imod < 0) imod=imod+iconv
1101  idat=idat*100+imod/3600
1102  imod=mod(imod,3600)
1103  idat=idat*100+imod/60
1104  imod=mod(imod,60)
1105  idat=idat*100+imod
1106endif
1107kdat=idat
1108end subroutine gregoi
1109function ijoursem(kdat)
1110! --------------------------------------------------------------------------
1111! **** *IJOURSEM* Jour de la semaine de la date d'entree.
1112! --------------------------------------------------------------------------
1113! Auteur:
1114! -------
1115! 94-10-31, J.M. Piriou.
1116!
1117! Modifications:
1118! --------------
1119!
1120! --------------------------------------------------------------------------
1121! En entree:
1122! kdat1 au format AAAAMMQQ
1123! En sortie:
1124! ijour=0 si dimanche, 1 lundi, ..., 6 samedi.
1125! --------------------------------------------------------------------------
1126
1127
1128IMPLICIT NONE
1129INTEGER(KIND=4) :: IDATDIM
1130INTEGER(KIND=4) :: IECART
1131INTEGER(KIND=4) :: IGRE
1132INTEGER(KIND=4) :: IGREDIM
1133INTEGER(KIND=4) :: KDAT
1134INTEGER(KIND=4) :: ijoursem
1135call gregod(kdat,1,igre)
1136idatdim=19941030 ! cette date etait un dimanche.
1137call gregod(idatdim,1,igredim)
1138iecart=igre-igredim
1139ijoursem=modulo(iecart,7)
1140end function ijoursem
1141
1142subroutine qqmmaa(kdatd,cdresd)
1143! --------------------------------------------------------------------------
1144! **** *QQMMAA *  - Conversion d'un entier type AAAAQQMM vers une date en clair.
1145! --------------------------------------------------------------------------
1146! Auteur:
1147! -------
1148! 92-05-27, J.M. Piriou.
1149!
1150! Modifications:
1151! --------------
1152!
1153! --------------------------------------------------------------------------
1154
1155
1156IMPLICIT NONE
1157INTEGER(KIND=4) :: IAN
1158INTEGER(KIND=4) :: IGRE
1159INTEGER(KIND=4) :: ILOC
1160INTEGER(KIND=4) :: IMM
1161INTEGER(KIND=4) :: IQQ
1162INTEGER(KIND=4) :: KDATD
1163character*(*) cdresd
1164character*03 cljour
1165iqq=mod(kdatd,100)
1166iloc=kdatd/100
1167imm=mod(iloc,100)
1168ian=iloc/100
1169call gregod(kdatd,1,igre)
1170igre=mod(igre,7)
1171if(igre == 0) then
1172  cljour='Lun'
1173elseif(igre == 1) then
1174  cljour='Mar'
1175elseif(igre == 2) then
1176  cljour='Mer'
1177elseif(igre == 3) then
1178  cljour='Jeu'
1179elseif(igre == 4) then
1180  cljour='Ven'
1181elseif(igre == 5) then
1182  cljour='Sam'
1183elseif(igre == 6) then
1184  cljour='Dim'
1185endif
1186write(cdresd,fmt='(a3,a1,i2,a1,i2.2,a1,i4.4)')&
1187&cljour,' ',iqq,'.',imm,'.',ian
1188end subroutine qqmmaa
1189
1190subroutine quant(kdate,kquant)
1191! --------------------------------------------------------------
1192! **** *quant* Quantieme de l'annee d'une date donnee.
1193! --------------------------------------------------------------
1194! Sujet:
1195! Arguments explicites:
1196! Arguments implicites:
1197! Methode:
1198! Externes:
1199! Auteur:   1999-04, J.M. Piriou.
1200! Modifications:
1201! --------------------------------------------------------------
1202! En entree:
1203! kdate date au format AAAAMMQQ.
1204! En sortie:
1205! quantieme de l'annee (1 le 1er janvier, 32 le 1er fevrier, etc...)
1206! --------------------------------------------------------------
1207
1208
1209IMPLICIT NONE
1210INTEGER(KIND=4) :: IBASE
1211INTEGER(KIND=4) :: IEC
1212INTEGER(KIND=4) :: KDATE
1213INTEGER(KIND=4) :: KQUANT
1214ibase=10000*(kdate/10000)+0101 ! 1er janvier de l'annee courante.
1215call ecartdj(ibase,kdate,iec)
1216kquant=iec+1
1217end subroutine quant
Note: See TracBrowser for help on using the repository browser.