1 |
guez |
30 |
MODULE calendar |
2 |
guez |
36 |
|
3 |
|
|
! From IOIPSL/src/calendar.f90, version 2.0 2004/04/05 14:47:47 |
4 |
|
|
|
5 |
guez |
62 |
! This is the calendar used to do all calculations on time. Three |
6 |
|
|
! types of calendars are possible: |
7 |
guez |
36 |
|
8 |
guez |
62 |
! - Gregorian: |
9 |
|
|
! The normal calendar. The time origin for the julian day in this |
10 |
|
|
! case is 24 Nov -4713. |
11 |
|
|
|
12 |
|
|
! - No leap: |
13 |
|
|
! A 365 day year without leap years. The origin for the julian days |
14 |
|
|
! is in this case 1 Jan 0. |
15 |
|
|
|
16 |
|
|
! - xxxd: |
17 |
|
|
! Year of xxx days with months of equal length. The origin for the |
18 |
|
|
! julian days is then also 1 Jan 0. |
19 |
|
|
|
20 |
|
|
! As one can see it is difficult to go from one calendar to the |
21 |
|
|
! other. All operations involving julian days will be wrong. This |
22 |
|
|
! calendar will lock as soon as possible the length of the year and |
23 |
|
|
! forbid any further modification. |
24 |
|
|
|
25 |
|
|
! For the non leap-year calendar the method is still brute force. |
26 |
|
|
! We need to find an integer series which takes care of the length |
27 |
|
|
! of the various month. (Jan) |
28 |
|
|
|
29 |
|
|
USE strlowercase_m, ONLY: strlowercase |
30 |
|
|
USE errioipsl, ONLY: histerr |
31 |
|
|
|
32 |
|
|
IMPLICIT NONE |
33 |
|
|
|
34 |
guez |
30 |
PRIVATE |
35 |
guez |
62 |
PUBLIC ymds2ju, ju2ymds, isittime, ioconf_calendar, itau2date, lock_unan, & |
36 |
|
|
calendar_used, un_an, un_jour |
37 |
guez |
30 |
|
38 |
guez |
62 |
REAL, PARAMETER:: un_jour = 86400. ! one day in seconds |
39 |
|
|
|
40 |
|
|
! Description of calendar |
41 |
|
|
|
42 |
|
|
CHARACTER(LEN=20):: calendar_used = "gregorian" |
43 |
|
|
LOGICAL:: lock_unan = .FALSE. |
44 |
|
|
REAL:: un_an = 365.2425 ! one year in days |
45 |
|
|
INTEGER:: mon_len(12) = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
46 |
|
|
|
47 |
|
|
CHARACTER(LEN=3), PARAMETER:: cal(12) = (/'JAN', 'FEB', 'MAR', 'APR', & |
48 |
|
|
'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'/) |
49 |
|
|
|
50 |
|
|
REAL, SAVE:: start_day, start_sec |
51 |
|
|
|
52 |
guez |
30 |
CONTAINS |
53 |
|
|
|
54 |
guez |
62 |
SUBROUTINE ymds2ju (year, month, day, sec, julian) |
55 |
guez |
30 |
|
56 |
guez |
62 |
INTEGER, INTENT(IN):: year, month, day |
57 |
|
|
REAL, INTENT(IN):: sec |
58 |
|
|
REAL, INTENT(OUT):: julian |
59 |
guez |
30 |
|
60 |
guez |
62 |
INTEGER:: julian_day |
61 |
|
|
REAL:: julian_sec |
62 |
guez |
30 |
|
63 |
guez |
62 |
!-------------------------------------------------------------------- |
64 |
guez |
30 |
|
65 |
guez |
62 |
CALL ymds2ju_internal(year, month, day, sec, julian_day, julian_sec) |
66 |
guez |
36 |
julian = julian_day + julian_sec / un_jour |
67 |
guez |
62 |
|
68 |
guez |
30 |
END SUBROUTINE ymds2ju |
69 |
|
|
|
70 |
|
|
!=== |
71 |
|
|
|
72 |
guez |
62 |
SUBROUTINE ymds2ju_internal (year, month, day, sec, julian_day, julian_sec) |
73 |
guez |
30 |
|
74 |
guez |
62 |
! Converts year, month, day and seconds into a julian day |
75 |
guez |
30 |
|
76 |
guez |
62 |
! In 1968 in a letter to the editor of Communications of the ACM |
77 |
|
|
! (CACM, volume 11, number 10, October 1968, p.657) Henry F. Fliegel |
78 |
|
|
! and Thomas C. Van Flandern presented such an algorithm. |
79 |
guez |
30 |
|
80 |
guez |
62 |
! See also: http://www.magnet.ch/serendipity/hermetic/cal_stud/jdn.htm |
81 |
guez |
30 |
|
82 |
guez |
62 |
! In the case of the Gregorian calendar we have chosen to use |
83 |
|
|
! the Lilian day numbers. This is the day counter which starts |
84 |
|
|
! on the 15th October 1582. |
85 |
|
|
! This is the day at which Pope Gregory XIII introduced the |
86 |
|
|
! Gregorian calendar. |
87 |
|
|
! Compared to the true Julian calendar, which starts some |
88 |
|
|
! 7980 years ago, the Lilian days are smaler and are dealt with |
89 |
|
|
! easily on 32 bit machines. With the true Julian days you can only |
90 |
|
|
! the fraction of the day in the real part to a precision of |
91 |
|
|
! a 1/4 of a day with 32 bits. |
92 |
guez |
30 |
|
93 |
guez |
62 |
INTEGER, INTENT(IN):: year, month, day |
94 |
|
|
REAL, INTENT(IN):: sec |
95 |
guez |
30 |
|
96 |
guez |
62 |
INTEGER, INTENT(OUT):: julian_day |
97 |
|
|
REAL, INTENT(OUT):: julian_sec |
98 |
|
|
|
99 |
|
|
INTEGER:: jd, m, y, d, ml |
100 |
|
|
!-------------------------------------------------------------------- |
101 |
guez |
30 |
lock_unan = .TRUE. |
102 |
|
|
|
103 |
|
|
m = month |
104 |
|
|
y = year |
105 |
|
|
d = day |
106 |
|
|
|
107 |
guez |
62 |
! We deduce the calendar from the length of the year as it |
108 |
|
|
! is faster than an INDEX on the calendar variable. |
109 |
guez |
30 |
|
110 |
guez |
62 |
! Gregorian |
111 |
guez |
30 |
IF ( (un_an > 365.0).AND.(un_an < 366.0) ) THEN |
112 |
|
|
jd = (1461*(y+4800+INT(( m-14 )/12)))/4 & |
113 |
|
|
& +(367*(m-2-12*(INT(( m-14 )/12))))/12 & |
114 |
|
|
& -(3*((y+4900+INT((m-14)/12))/100))/4 & |
115 |
|
|
& +d-32075 |
116 |
|
|
jd = jd-2299160 |
117 |
guez |
62 |
! No leap or All leap |
118 |
guez |
30 |
ELSE IF (ABS(un_an-365.0) <= EPSILON(un_an) .OR. & |
119 |
|
|
& ABS(un_an-366.0) <= EPSILON(un_an)) THEN |
120 |
|
|
ml = SUM(mon_len(1:m-1)) |
121 |
|
|
jd = y*INT(un_an)+ml+(d-1) |
122 |
guez |
62 |
! Calendar with regular month |
123 |
guez |
30 |
ELSE |
124 |
|
|
ml = INT(un_an)/12 |
125 |
|
|
jd = y*INT(un_an)+(m-1)*ml+(d-1) |
126 |
|
|
ENDIF |
127 |
|
|
|
128 |
|
|
julian_day = jd |
129 |
|
|
julian_sec = sec |
130 |
guez |
62 |
|
131 |
guez |
30 |
END SUBROUTINE ymds2ju_internal |
132 |
guez |
62 |
|
133 |
guez |
30 |
!=== |
134 |
|
|
|
135 |
guez |
62 |
SUBROUTINE ju2ymds (julian, year, month, day, sec) |
136 |
guez |
30 |
|
137 |
guez |
62 |
REAL, INTENT(IN):: julian |
138 |
guez |
30 |
|
139 |
guez |
62 |
INTEGER, INTENT(OUT):: year, month, day |
140 |
|
|
REAL, INTENT(OUT):: sec |
141 |
|
|
|
142 |
|
|
INTEGER:: julian_day |
143 |
|
|
REAL:: julian_sec |
144 |
|
|
!-------------------------------------------------------------------- |
145 |
guez |
30 |
julian_day = INT(julian) |
146 |
|
|
julian_sec = (julian-julian_day)*un_jour |
147 |
|
|
|
148 |
guez |
62 |
CALL ju2ymds_internal(julian_day, julian_sec, year, month, day, sec) |
149 |
|
|
|
150 |
guez |
30 |
END SUBROUTINE ju2ymds |
151 |
guez |
62 |
|
152 |
guez |
30 |
!=== |
153 |
|
|
|
154 |
guez |
62 |
SUBROUTINE ju2ymds_internal (julian_day, julian_sec, year, month, day, sec) |
155 |
guez |
30 |
|
156 |
guez |
62 |
! This subroutine computes from the julian day the year, |
157 |
|
|
! month, day and seconds |
158 |
guez |
30 |
|
159 |
guez |
62 |
! In 1968 in a letter to the editor of Communications of the ACM |
160 |
|
|
! (CACM, volume 11, number 10, October 1968, p.657) Henry F. Fliegel |
161 |
|
|
! and Thomas C. Van Flandern presented such an algorithm. |
162 |
guez |
30 |
|
163 |
guez |
62 |
! See also: http://www.magnet.ch/serendipity/hermetic/cal_stud/jdn.htm |
164 |
guez |
30 |
|
165 |
guez |
62 |
! In the case of the Gregorian calendar we have chosen to use |
166 |
|
|
! the Lilian day numbers. This is the day counter which starts |
167 |
|
|
! on the 15th October 1582. This is the day at which Pope |
168 |
|
|
! Gregory XIII introduced the Gregorian calendar. |
169 |
|
|
! Compared to the true Julian calendar, which starts some 7980 |
170 |
|
|
! years ago, the Lilian days are smaler and are dealt with easily |
171 |
|
|
! on 32 bit machines. With the true Julian days you can only the |
172 |
|
|
! fraction of the day in the real part to a precision of a 1/4 of |
173 |
|
|
! a day with 32 bits. |
174 |
guez |
30 |
|
175 |
guez |
62 |
INTEGER, INTENT(IN):: julian_day |
176 |
|
|
REAL, INTENT(IN):: julian_sec |
177 |
|
|
|
178 |
|
|
INTEGER, INTENT(OUT):: year, month, day |
179 |
|
|
REAL, INTENT(OUT):: sec |
180 |
|
|
|
181 |
|
|
INTEGER:: l, n, i, jd, j, d, m, y, ml |
182 |
|
|
INTEGER:: add_day |
183 |
|
|
!-------------------------------------------------------------------- |
184 |
guez |
30 |
lock_unan = .TRUE. |
185 |
|
|
|
186 |
|
|
jd = julian_day |
187 |
|
|
sec = julian_sec |
188 |
|
|
IF (sec > un_jour) THEN |
189 |
|
|
add_day = INT(sec/un_jour) |
190 |
|
|
sec = sec-add_day*un_jour |
191 |
|
|
jd = jd+add_day |
192 |
|
|
ENDIF |
193 |
|
|
|
194 |
guez |
62 |
! Gregorian |
195 |
guez |
30 |
IF ( (un_an > 365.0).AND.(un_an < 366.0) ) THEN |
196 |
|
|
jd = jd+2299160 |
197 |
|
|
|
198 |
|
|
l = jd+68569 |
199 |
|
|
n = (4*l)/146097 |
200 |
|
|
l = l-(146097*n+3)/4 |
201 |
|
|
i = (4000*(l+1))/1461001 |
202 |
|
|
l = l-(1461*i)/4+31 |
203 |
|
|
j = (80*l)/2447 |
204 |
|
|
d = l-(2447*j)/80 |
205 |
|
|
l = j/11 |
206 |
|
|
m = j+2-(12*l) |
207 |
|
|
y = 100*(n-49)+i+l |
208 |
guez |
62 |
! No leap or All leap |
209 |
guez |
30 |
ELSE IF (ABS(un_an-365.0) <= EPSILON(un_an) .OR. & |
210 |
|
|
& ABS(un_an-366.0) <= EPSILON(un_an) ) THEN |
211 |
|
|
y = jd/INT(un_an) |
212 |
|
|
l = jd-y*INT(un_an) |
213 |
|
|
m = 1 |
214 |
|
|
ml = 0 |
215 |
|
|
DO WHILE (ml+mon_len(m) <= l) |
216 |
|
|
ml = ml+mon_len(m) |
217 |
|
|
m = m+1 |
218 |
|
|
ENDDO |
219 |
|
|
d = l-ml+1 |
220 |
guez |
62 |
! others |
221 |
guez |
30 |
ELSE |
222 |
|
|
ml = INT(un_an)/12 |
223 |
|
|
y = jd/INT(un_an) |
224 |
|
|
l = jd-y*INT(un_an) |
225 |
|
|
m = (l/ml)+1 |
226 |
|
|
d = l-(m-1)*ml+1 |
227 |
|
|
ENDIF |
228 |
|
|
|
229 |
|
|
day = d |
230 |
|
|
month = m |
231 |
|
|
year = y |
232 |
guez |
62 |
|
233 |
guez |
30 |
END SUBROUTINE ju2ymds_internal |
234 |
guez |
62 |
|
235 |
guez |
30 |
!=== |
236 |
|
|
|
237 |
guez |
62 |
REAL FUNCTION itau2date (itau, date0, deltat) |
238 |
guez |
30 |
|
239 |
guez |
62 |
! This function transforms itau into a date. The date whith which |
240 |
|
|
! the time axis is going to be labeled |
241 |
guez |
30 |
|
242 |
guez |
62 |
! INPUT |
243 |
|
|
! itau: current time step |
244 |
|
|
! date0: Date at which itau was equal to 0 |
245 |
|
|
! deltat: time step between itau s |
246 |
|
|
|
247 |
|
|
! OUTPUT |
248 |
|
|
! itau2date: Date for the given itau |
249 |
|
|
|
250 |
|
|
INTEGER:: itau |
251 |
|
|
REAL:: date0, deltat |
252 |
|
|
!-------------------------------------------------------------------- |
253 |
guez |
30 |
itau2date = REAL(itau)*deltat/un_jour+date0 |
254 |
guez |
62 |
|
255 |
guez |
30 |
END FUNCTION itau2date |
256 |
guez |
62 |
|
257 |
guez |
30 |
!=== |
258 |
guez |
62 |
|
259 |
guez |
30 |
SUBROUTINE isittime & |
260 |
guez |
62 |
& (itau, date0, dt, freq, last_action, last_check, do_action) |
261 |
guez |
30 |
|
262 |
guez |
62 |
! This subroutine checks the time has come for a given action. |
263 |
|
|
! This is computed from the current time-step(itau). |
264 |
|
|
! Thus we need to have the time delta (dt), the frequency |
265 |
|
|
! of the action (freq) and the last time it was done |
266 |
|
|
! (last_action in units of itau). |
267 |
|
|
! In order to extrapolate when will be the next check we need |
268 |
|
|
! the time step of the last call (last_check). |
269 |
guez |
30 |
|
270 |
guez |
62 |
! The test is done on the following condition: |
271 |
|
|
! the distance from the current time to the time for the next |
272 |
|
|
! action is smaller than the one from the next expected |
273 |
|
|
! check to the next action. |
274 |
|
|
! When the test is done on the time steps simplifactions make |
275 |
|
|
! it more difficult to read in the code. |
276 |
|
|
! For the real time case it is easier to understand ! |
277 |
guez |
30 |
|
278 |
guez |
62 |
INTEGER, INTENT(IN):: itau |
279 |
|
|
REAL, INTENT(IN):: dt, freq |
280 |
|
|
INTEGER, INTENT(IN):: last_action, last_check |
281 |
|
|
REAL, INTENT(IN):: date0 |
282 |
guez |
30 |
|
283 |
guez |
62 |
LOGICAL, INTENT(OUT):: do_action |
284 |
|
|
|
285 |
|
|
REAL:: dt_action, dt_check |
286 |
|
|
REAL:: date_last_act, date_next_check, date_next_act, & |
287 |
|
|
& date_now, date_mp1, date_mpf |
288 |
|
|
INTEGER:: year, month, monthp1, day, next_check_itau, next_act_itau |
289 |
|
|
INTEGER:: yearp, dayp |
290 |
|
|
REAL:: sec, secp |
291 |
|
|
LOGICAL:: check = .FALSE. |
292 |
|
|
!-------------------------------------------------------------------- |
293 |
guez |
30 |
IF (check) THEN |
294 |
guez |
62 |
WRITE(*, *) & |
295 |
|
|
& "isittime 1.0 ", itau, date0, dt, freq, last_action, last_check |
296 |
guez |
30 |
ENDIF |
297 |
|
|
|
298 |
|
|
IF (last_check >= 0) THEN |
299 |
|
|
dt_action = (itau-last_action)*dt |
300 |
|
|
dt_check = (itau-last_check)*dt |
301 |
|
|
next_check_itau = itau+(itau-last_check) |
302 |
|
|
|
303 |
guez |
62 |
!- We are dealing with frequencies in seconds and thus operation |
304 |
|
|
!- can be done on the time steps. |
305 |
guez |
30 |
|
306 |
|
|
IF (freq > 0) THEN |
307 |
|
|
IF (ABS(dt_action-freq) <= ABS(dt_action+dt_check-freq)) THEN |
308 |
|
|
do_action = .TRUE. |
309 |
|
|
ELSE |
310 |
|
|
do_action = .FALSE. |
311 |
|
|
ENDIF |
312 |
|
|
|
313 |
guez |
62 |
!--- Here we deal with frequencies in month and work on julian days. |
314 |
guez |
30 |
|
315 |
|
|
ELSE |
316 |
guez |
62 |
date_now = itau2date (itau, date0, dt) |
317 |
|
|
date_last_act = itau2date (last_action, date0, dt) |
318 |
|
|
CALL ju2ymds (date_last_act, year, month, day, sec) |
319 |
guez |
35 |
monthp1 = month - freq |
320 |
guez |
30 |
yearp = year |
321 |
|
|
|
322 |
guez |
62 |
!--- Here we compute what logically should be the next month |
323 |
guez |
30 |
|
324 |
|
|
IF (month >= 13) THEN |
325 |
|
|
yearp = year+1 |
326 |
|
|
monthp1 = monthp1-12 |
327 |
|
|
ENDIF |
328 |
guez |
62 |
CALL ymds2ju (year, monthp1, day, sec, date_mpf) |
329 |
guez |
30 |
|
330 |
guez |
62 |
!--- But it could be that because of a shorter month or a bad |
331 |
|
|
!--- starting date that we end up further than we should be. |
332 |
|
|
!--- Thus we compute the first day of the next month. |
333 |
|
|
!--- We can not be beyond this date and if we are close |
334 |
|
|
!--- then we will take it as it is better. |
335 |
guez |
30 |
|
336 |
|
|
monthp1 = month+ABS(freq) |
337 |
|
|
yearp=year |
338 |
|
|
IF (monthp1 >= 13) THEN |
339 |
|
|
yearp = year+1 |
340 |
|
|
monthp1 = monthp1 -12 |
341 |
|
|
ENDIF |
342 |
|
|
dayp = 1 |
343 |
|
|
secp = 0.0 |
344 |
guez |
62 |
CALL ymds2ju (yearp, monthp1, dayp, secp, date_mp1) |
345 |
guez |
30 |
|
346 |
guez |
62 |
!--- If date_mp1 is smaller than date_mpf or only less than 4 days |
347 |
|
|
!--- larger then we take it. This needed to ensure that short month |
348 |
|
|
!--- like February do not mess up the thing ! |
349 |
guez |
30 |
|
350 |
|
|
IF (date_mp1-date_mpf < 4.) THEN |
351 |
|
|
date_next_act = date_mp1 |
352 |
|
|
ELSE |
353 |
|
|
date_next_act = date_mpf |
354 |
|
|
ENDIF |
355 |
guez |
62 |
date_next_check = itau2date (next_check_itau, date0, dt) |
356 |
guez |
30 |
|
357 |
guez |
62 |
!--- Transform the dates into time-steps for the needed precisions. |
358 |
guez |
30 |
|
359 |
|
|
next_act_itau = & |
360 |
|
|
& last_action+INT((date_next_act-date_last_act)*(un_jour/dt)) |
361 |
guez |
62 |
|
362 |
guez |
30 |
IF ( ABS(itau-next_act_itau) & |
363 |
|
|
& <= ABS( next_check_itau-next_act_itau)) THEN |
364 |
|
|
do_action = .TRUE. |
365 |
|
|
IF (check) THEN |
366 |
guez |
62 |
WRITE(*, *) & |
367 |
|
|
& 'ACT-TIME: itau, next_act_itau, next_check_itau: ', & |
368 |
|
|
& itau, next_act_itau, next_check_itau |
369 |
|
|
CALL ju2ymds (date_now, year, month, day, sec) |
370 |
|
|
WRITE(*, *) 'ACT-TIME: y, m, d, s: ', year, month, day, sec |
371 |
|
|
WRITE(*, *) & |
372 |
|
|
& 'ACT-TIME: date_mp1, date_mpf: ', date_mp1, date_mpf |
373 |
guez |
30 |
ENDIF |
374 |
|
|
ELSE |
375 |
|
|
do_action = .FALSE. |
376 |
|
|
ENDIF |
377 |
|
|
ENDIF |
378 |
|
|
|
379 |
|
|
IF (check) THEN |
380 |
guez |
62 |
WRITE(*, *) "isittime 2.0 ", & |
381 |
|
|
& date_next_check, date_next_act, ABS(dt_action-freq), & |
382 |
|
|
& ABS(dt_action+dt_check-freq), dt_action, dt_check, & |
383 |
|
|
& next_check_itau, do_action |
384 |
guez |
30 |
ENDIF |
385 |
|
|
ELSE |
386 |
|
|
do_action=.FALSE. |
387 |
|
|
ENDIF |
388 |
guez |
62 |
|
389 |
guez |
30 |
END SUBROUTINE isittime |
390 |
guez |
62 |
|
391 |
guez |
30 |
!=== |
392 |
guez |
62 |
|
393 |
guez |
30 |
SUBROUTINE ioconf_calendar (str) |
394 |
|
|
|
395 |
guez |
62 |
! This routine allows to configure the calendar to be used. |
396 |
|
|
! This operation is only allowed once and the first call to |
397 |
|
|
! ymds2ju or ju2ymsd will lock the current configuration. |
398 |
|
|
! the argument to ioconf_calendar can be any of the following: |
399 |
|
|
! - gregorian: This is the gregorian calendar (default here) |
400 |
|
|
! - noleap: A calendar without leap years = 365 days |
401 |
|
|
! - xxxd: A calendar of xxx days (has to be a modulo of 12) |
402 |
|
|
! with 12 month of equal length |
403 |
guez |
30 |
|
404 |
guez |
62 |
CHARACTER(LEN=*), INTENT(IN):: str |
405 |
guez |
30 |
|
406 |
guez |
62 |
INTEGER:: leng, ipos |
407 |
|
|
CHARACTER(LEN=10):: str10 |
408 |
|
|
!-------------------------------------------------------------------- |
409 |
|
|
|
410 |
guez |
30 |
! 1.0 Clean up the sring ! |
411 |
|
|
|
412 |
|
|
CALL strlowercase (str) |
413 |
|
|
|
414 |
|
|
IF (.NOT.lock_unan) THEN |
415 |
guez |
62 |
|
416 |
guez |
30 |
lock_unan=.TRUE. |
417 |
guez |
62 |
|
418 |
guez |
30 |
SELECT CASE(str) |
419 |
|
|
CASE('gregorian') |
420 |
|
|
calendar_used = 'gregorian' |
421 |
|
|
un_an = 365.2425 |
422 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
423 |
guez |
30 |
CASE('standard') |
424 |
|
|
calendar_used = 'gregorian' |
425 |
|
|
un_an = 365.2425 |
426 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
427 |
guez |
30 |
CASE('proleptic_gregorian') |
428 |
|
|
calendar_used = 'gregorian' |
429 |
|
|
un_an = 365.2425 |
430 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
431 |
guez |
30 |
CASE('noleap') |
432 |
|
|
calendar_used = 'noleap' |
433 |
|
|
un_an = 365.0 |
434 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
435 |
guez |
30 |
CASE('365_day') |
436 |
|
|
calendar_used = 'noleap' |
437 |
|
|
un_an = 365.0 |
438 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
439 |
guez |
30 |
CASE('365d') |
440 |
|
|
calendar_used = 'noleap' |
441 |
|
|
un_an = 365.0 |
442 |
guez |
62 |
mon_len(:)=(/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
443 |
guez |
30 |
CASE('all_leap') |
444 |
|
|
calendar_used = 'all_leap' |
445 |
|
|
un_an = 366.0 |
446 |
guez |
62 |
mon_len(:)=(/31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
447 |
guez |
30 |
CASE('366_day') |
448 |
|
|
calendar_used = 'all_leap' |
449 |
|
|
un_an = 366.0 |
450 |
guez |
62 |
mon_len(:)=(/31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
451 |
guez |
30 |
CASE('366d') |
452 |
|
|
calendar_used = 'all_leap' |
453 |
|
|
un_an = 366.0 |
454 |
guez |
62 |
mon_len(:)=(/31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/) |
455 |
guez |
30 |
CASE DEFAULT |
456 |
guez |
62 |
ipos = INDEX(str, 'd') |
457 |
guez |
30 |
IF (ipos == 4) THEN |
458 |
guez |
62 |
READ(str(1:3), '(I3)') leng |
459 |
|
|
IF ( (MOD(leng, 12) == 0).AND.(leng > 1) ) THEN |
460 |
guez |
30 |
calendar_used = str |
461 |
|
|
un_an = leng |
462 |
|
|
mon_len(:) = leng |
463 |
|
|
ELSE |
464 |
guez |
62 |
CALL histerr (3, 'ioconf_calendar', & |
465 |
guez |
30 |
& 'The length of the year as to be a modulo of 12', & |
466 |
|
|
& 'so that it can be divided into 12 month of equal length', & |
467 |
|
|
& str) |
468 |
|
|
ENDIF |
469 |
|
|
ELSE |
470 |
guez |
62 |
CALL histerr (3, 'ioconf_calendar', & |
471 |
|
|
& 'Unrecognized input, please ceck the man pages.', str, ' ') |
472 |
guez |
30 |
ENDIF |
473 |
|
|
END SELECT |
474 |
|
|
ELSE |
475 |
guez |
62 |
WRITE(str10, '(f10.4)') un_an |
476 |
|
|
CALL histerr (2, 'ioconf_calendar', & |
477 |
guez |
30 |
& 'The calendar was already used or configured. You are not', & |
478 |
|
|
& 'allowed to change it again. '// & |
479 |
guez |
62 |
& 'The following length of year is used:', str10) |
480 |
guez |
30 |
ENDIF |
481 |
guez |
62 |
|
482 |
guez |
30 |
END SUBROUTINE ioconf_calendar |
483 |
|
|
|
484 |
|
|
END MODULE calendar |