updated top-level README and version_decl for V4.5 (#1847)
[WRF.git] / var / obsproc / src / module_date.F90
blob1f24b661267ebc81bd43776ede5f3793efde00d8
1 MODULE module_date
3 !  This module is able to perform three date and time functions:
5 !  1.  geth_idts (ndate, odate, idts, pass, iunit)
6 !  Get the time period between two dates.
8 !  2. geth_newdate ( ndate, odate, idts)
9 !  Get the new date based on the old date and a time difference.
11 !  3. split_date_char (date, century_year, month, day, hour, minute, second )
12 !  Given the date, return the integer components.
14 ! 4. make_date ( date , time , date_time_char )
15 !  takes an 8-digit date (YYYYMMDD) and a 6-digit time (HHmmss) and 
16 !  converts it to a 24-digit string (YYYY-MM-DD_HH:mm:ss.ffff).
18 !  5.  geth_idts_2 (ndate, odate, idts, pass, iunit)
19 !  Get the time period between two dates without changing ndate or odate.
22 CONTAINS
24 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
26    SUBROUTINE geth_idts (ndate, odate, idts, pass, iunit)
27    
28       IMPLICIT NONE
29       
30       !  From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'), 
31       !  compute the time difference.
32       
33       !  on entry     -  ndate  -  the new hdate.
34       !                  odate  -  the old hdate.
35       !  on entry     -  iunit   -  logical unit to output error messages
36       
37       !  on exit      -  idts    -  the change in time in seconds.
38       !  on exit      -  pass    -  False if input sting is not a date
39       
40       CHARACTER (LEN=*) , INTENT(INOUT) :: ndate, odate
41       INTEGER           , INTENT(OUT)   :: idts
42       LOGICAL, OPTIONAL                 :: pass
43       INTEGER, OPTIONAL                 :: iunit
45       !  Local Variables
46       
47       !  yrnew    -  indicates the year associated with "ndate"
48       !  yrold    -  indicates the year associated with "odate"
49       !  monew    -  indicates the month associated with "ndate"
50       !  moold    -  indicates the month associated with "odate"
51       !  dynew    -  indicates the day associated with "ndate"
52       !  dyold    -  indicates the day associated with "odate"
53       !  hrnew    -  indicates the hour associated with "ndate"
54       !  hrold    -  indicates the hour associated with "odate"
55       !  minew    -  indicates the minute associated with "ndate"
56       !  miold    -  indicates the minute associated with "odate"
57       !  scnew    -  indicates the second associated with "ndate"
58       !  scold    -  indicates the second associated with "odate"
59       !  i        -  loop counter
60       !  mday     -  a list assigning the number of days in each month
61       !  iout     -  logical unit to output error messages (default 0)
62       
63       CHARACTER (LEN=24) :: tdate
64       INTEGER :: olen, nlen
65       INTEGER :: yrnew, monew, dynew, hrnew, minew, scnew
66       INTEGER :: yrold, moold, dyold, hrold, miold, scold
67       INTEGER :: mday(12), i, newdys, olddys
68       LOGICAL :: npass, opass
69       INTEGER :: isign, iout
71       IF (odate.GT.ndate) THEN
72          isign = -1
73          tdate=ndate
74          ndate=odate
75          odate=tdate
76       ELSE
77          isign = 1
78       END IF
79       
80       !  Assign the number of days in a months
81       
82       mday( 1) = 31
83       mday( 2) = 28
84       mday( 3) = 31
85       mday( 4) = 30
86       mday( 5) = 31
87       mday( 6) = 30
88       mday( 7) = 31
89       mday( 8) = 31
90       mday( 9) = 30
91       mday(10) = 31
92       mday(11) = 30
93       mday(12) = 31
94       
95       !  Break down old hdate into parts
96       
97       hrold = 0
98       miold = 0
99       scold = 0
100       olen = LEN(odate)
101       
102       READ(odate(1:4),  '(I4)') yrold
103       READ(odate(6:7),  '(I2)') moold
104       READ(odate(9:10), '(I2)') dyold
105       IF (olen.GE.13) THEN
106          READ(odate(12:13),'(I2)') hrold
107          IF (olen.GE.16) THEN
108             READ(odate(15:16),'(I2)') miold
109             IF (olen.GE.19) THEN
110                READ(odate(18:19),'(I2)') scold
111             END IF
112          END IF
113       END IF
114       
115       !  Break down new hdate into parts
116       
117       hrnew = 0
118       minew = 0
119       scnew = 0
120       nlen = LEN(ndate)
122       READ(ndate(1:4),  '(I4)') yrnew
123       READ(ndate(6:7),  '(I2)') monew
124       READ(ndate(9:10), '(I2)') dynew
125       IF (nlen.GE.13) THEN
126          READ(ndate(12:13),'(I2)') hrnew
127          IF (nlen.GE.16) THEN
128             READ(ndate(15:16),'(I2)') minew
129             IF (nlen.GE.19) THEN
130                READ(ndate(18:19),'(I2)') scnew
131             END IF
132          END IF
133       END IF
134       
135       !  Check that the dates make sense.
136       
137       npass = .true.
138       opass = .true.
140       iout = 0
141       IF (PRESENT (pass))  &
142           pass = .true.
143       IF (PRESENT (iunit)) &
144           iout =  iunit
145       
146       !  Check that the month of NDATE makes sense.
147       
148       IF ((monew.GT.12).or.(monew.LT.1)) THEN
149          WRITE (iout,'(A,A)') ' GETH_IDTS:  Month of NDATE = ', monew
150          npass = .false.
151       END IF
152       
153       !  Check that the month of ODATE makes sense.
154       
155       IF ((moold.GT.12).or.(moold.LT.1)) THEN
156          WRITE (iout,'(A,I2)') ' GETH_IDTS:  Month of ODATE = ', moold
157          opass = .false.
158       END IF
159       
160       !  Check that the day of NDATE makes sense.
161       
162       IF (monew.ne.2) THEN
163       ! ...... For all months but February
164          IF ((dynew.GT.mday(monew)).or.(dynew.LT.1)) THEN
165 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of NDATE = ', dynew
166             npass = .false.
167          END IF
168       ELSE IF (monew.eq.2) THEN
169       ! ...... For February
170          IF ((dynew.GT.nfeb(yrnew)).or.(dynew.LT.1)) THEN
171 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of NDATE = ', dynew
172             npass = .false.
173          END IF
174       END IF
175       
176       !  Check that the day of ODATE makes sense.
177       
178       IF (moold.ne.2) THEN
179       ! ...... For all months but February
180          IF ((dyold.GT.mday(moold)).OR.(dyold.LT.1)) THEN
181 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of ODATE = ', dyold
182             opass = .false.
183          END IF
184       ELSE IF (moold.eq.2) THEN
185       ! ....... For February
186          IF ((dyold.GT.nfeb(yrold)).OR.(dyold.LT.1)) THEN
187 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of ODATE = ', dyold
188             opass = .false.
189          END IF
190       END IF
191       
192       !  Check that the hour of NDATE makes sense.
193       
194       IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
195 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Hour of NDATE = ', hrnew
196          npass = .false.
197       END IF
198       
199       !  Check that the hour of ODATE makes sense.
200       
201       IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
202 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Hour of ODATE = ', hrold
203          opass = .false.
204       END IF
205       
206       !  Check that the minute of NDATE makes sense.
207       
208       IF ((minew.GT.59).or.(minew.LT.0)) THEN
209             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Minute of NDATE = ', minew
210          npass = .false.
211       END IF
212       
213       !  Check that the minute of ODATE makes sense.
214       
215       IF ((miold.GT.59).or.(miold.LT.0)) THEN
216             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Minute of ODATE = ', miold
217          opass = .false.
218       END IF
219       
220       !  Check that the second of NDATE makes sense.
221       
222       IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
223             WRITE (iout,'(A,I2)') ' GETH_IDTS:  SECOND of NDATE = ', scnew
224          npass = .false.
225       END IF
226       
227       !  Check that the second of ODATE makes sense.
228       
229       IF ((scold.GT.59).or.(scold.LT.0)) THEN
230             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Second of ODATE = ', scold
231          opass = .false.
232       END IF
233       
234       IF (.not. npass) THEN
235          IF (PRESENT (pass)) THEN
236              idts = 0
237              pass = .false.
238              WRITE (iout,'(A,A)') 'Screwy NDATE: ', ndate(1:nlen)
239              IF (isign == -1) THEN
240                  tdate=ndate
241                  ndate=odate
242                  odate=tdate
243              ENDIF
244              RETURN
245          ELSE
246              STOP 'ndate_2'
247          ENDIF
248       END IF
249       
250       IF (.not. opass) THEN
251          IF (PRESENT (pass)) THEN
252              idts = 0
253              pass = .false.
254              WRITE (iout,'(A,A)') 'Screwy ODATE: ', odate(1:nlen)
255              IF (isign == -1) THEN
256                  tdate=ndate
257                  ndate=odate
258                  odate=tdate
259              ENDIF
260              RETURN
261          ELSE
262              STOP 'odate_1'
263          ENDIF
264       END IF
265       
266       !  Date Checks are completed.  Continue.
267       
268       !  Compute number of days from 1 January ODATE, 00:00:00 until ndate
269       !  Compute number of hours from 1 January ODATE, 00:00:00 until ndate
270       !  Compute number of minutes from 1 January ODATE, 00:00:00 until ndate
271       
272       newdys = 0
273       DO i = yrold, yrnew - 1
274          newdys = newdys + 365 + (nfeb(i)-28)
275       END DO
276       
277       IF (monew .GT. 1) THEN
278          mday(2) = nfeb(yrnew)
279          DO i = 1, monew - 1
280             newdys = newdys + mday(i)
281          END DO
282          mday(2) = 28
283       END IF
284       
285       newdys = newdys + dynew-1
286       
287       !  Compute number of hours from 1 January ODATE, 00:00:00 until odate
288       !  Compute number of minutes from 1 January ODATE, 00:00:00 until odate
289       
290       olddys = 0
291       
292       IF (moold .GT. 1) THEN
293          mday(2) = nfeb(yrold)
294          DO i = 1, moold - 1
295             olddys = olddys + mday(i)
296          END DO
297          mday(2) = 28
298       END IF
299       
300       olddys = olddys + dyold-1
301       
302       !  Determine the time difference in seconds
303       
304       idts = (newdys - olddys) * 86400
305       idts = idts + (hrnew - hrold) * 3600
306       idts = idts + (minew - miold) * 60
307       idts = idts + (scnew - scold)
308       
309       IF (isign .eq. -1) THEN
310          tdate=ndate
311          ndate=odate
312          odate=tdate
313          idts = idts * isign
314       END IF
315    
316    END SUBROUTINE geth_idts
318 !------------------------------------------------------------------------------!
320    SUBROUTINE geth_idts_old (ndate, odate, idts)
321    
322       IMPLICIT NONE
323       
324       !  From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'), 
325       !  compute the time difference.
326       
327       !  on entry     -  ndate  -  the new hdate.
328       !                  odate  -  the old hdate.
329       
330       !  on exit      -  idts    -  the change in time in seconds.
331       
332       CHARACTER (LEN=*) , INTENT(INOUT) :: ndate, odate
333       INTEGER           , INTENT(OUT)   :: idts
334       
335       !  Local Variables
336       
337       !  yrnew    -  indicates the year associated with "ndate"
338       !  yrold    -  indicates the year associated with "odate"
339       !  monew    -  indicates the month associated with "ndate"
340       !  moold    -  indicates the month associated with "odate"
341       !  dynew    -  indicates the day associated with "ndate"
342       !  dyold    -  indicates the day associated with "odate"
343       !  hrnew    -  indicates the hour associated with "ndate"
344       !  hrold    -  indicates the hour associated with "odate"
345       !  minew    -  indicates the minute associated with "ndate"
346       !  miold    -  indicates the minute associated with "odate"
347       !  scnew    -  indicates the second associated with "ndate"
348       !  scold    -  indicates the second associated with "odate"
349       !  i        -  loop counter
350       !  mday     -  a list assigning the number of days in each month
351       
352       CHARACTER (LEN=24) :: tdate
353       INTEGER :: olen, nlen
354       INTEGER :: yrnew, monew, dynew, hrnew, minew, scnew
355       INTEGER :: yrold, moold, dyold, hrold, miold, scold
356       INTEGER :: mday(12), i, newdys, olddys
357       LOGICAL :: npass, opass
358       INTEGER :: isign
359       
360       IF (odate.GT.ndate) THEN
361          isign = -1
362          tdate=ndate
363          ndate=odate
364          odate=tdate
365       ELSE
366          isign = 1
367       END IF
368       
369       !  Assign the number of days in a months
370       
371       mday( 1) = 31
372       mday( 2) = 28
373       mday( 3) = 31
374       mday( 4) = 30
375       mday( 5) = 31
376       mday( 6) = 30
377       mday( 7) = 31
378       mday( 8) = 31
379       mday( 9) = 30
380       mday(10) = 31
381       mday(11) = 30
382       mday(12) = 31
383       
384       !  Break down old hdate into parts
385       
386       hrold = 0
387       miold = 0
388       scold = 0
389       olen = LEN(odate)
390       
391       READ(odate(1:4),  '(I4)') yrold
392       READ(odate(6:7),  '(I2)') moold
393       READ(odate(9:10), '(I2)') dyold
394       IF (olen.GE.13) THEN
395          READ(odate(12:13),'(I2)') hrold
396          IF (olen.GE.16) THEN
397             READ(odate(15:16),'(I2)') miold
398             IF (olen.GE.19) THEN
399                READ(odate(18:19),'(I2)') scold
400             END IF
401          END IF
402       END IF
403       
404       !  Break down new hdate into parts
405       
406       hrnew = 0
407       minew = 0
408       scnew = 0
409       nlen = LEN(ndate)
411       READ(ndate(1:4),  '(I4)') yrnew
412       READ(ndate(6:7),  '(I2)') monew
413       READ(ndate(9:10), '(I2)') dynew
414       IF (nlen.GE.13) THEN
415          READ(ndate(12:13),'(I2)') hrnew
416          IF (nlen.GE.16) THEN
417             READ(ndate(15:16),'(I2)') minew
418             IF (nlen.GE.19) THEN
419                READ(ndate(18:19),'(I2)') scnew
420             END IF
421          END IF
422       END IF
423       
424       !  Check that the dates make sense.
425       
426       npass = .true.
427       opass = .true.
428       
429       !  Check that the month of NDATE makes sense.
430       
431       IF ((monew.GT.12).or.(monew.LT.1)) THEN
432          PRINT*, 'GETH_IDTS:  Month of NDATE = ', monew
433          npass = .false.
434       END IF
435       
436       !  Check that the month of ODATE makes sense.
437       
438       IF ((moold.GT.12).or.(moold.LT.1)) THEN
439          PRINT*, 'GETH_IDTS:  Month of ODATE = ', moold
440          opass = .false.
441       END IF
442       
443       !  Check that the day of NDATE makes sense.
444       
445       IF (monew.ne.2) THEN
446       ! ...... For all months but February
447          IF ((dynew.GT.mday(monew)).or.(dynew.LT.1)) THEN
448             PRINT*, 'GETH_IDTS:  Day of NDATE = ', dynew
449             npass = .false.
450          END IF
451       ELSE IF (monew.eq.2) THEN
452       ! ...... For February
453          IF ((dynew.GT.nfeb(yrnew)).or.(dynew.LT.1)) THEN
454             PRINT*, 'GETH_IDTS:  Day of NDATE = ', dynew
455             npass = .false.
456          END IF
457       END IF
458       
459       !  Check that the day of ODATE makes sense.
460       
461       IF (moold.ne.2) THEN
462       ! ...... For all months but February
463          IF ((dyold.GT.mday(moold)).OR.(dyold.LT.1)) THEN
464             PRINT*, 'GETH_IDTS:  Day of ODATE = ', dyold
465             opass = .false.
466          END IF
467       ELSE IF (moold.eq.2) THEN
468       ! ....... For February
469          IF ((dyold.GT.nfeb(yrold)).OR.(dyold.LT.1)) THEN
470             PRINT*, 'GETH_IDTS:  Day of ODATE = ', dyold
471             opass = .false.
472          END IF
473       END IF
474       
475       !  Check that the hour of NDATE makes sense.
476       
477       IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
478          PRINT*, 'GETH_IDTS:  Hour of NDATE = ', hrnew
479          npass = .false.
480       END IF
481       
482       !  Check that the hour of ODATE makes sense.
483       
484       IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
485          PRINT*, 'GETH_IDTS:  Hour of ODATE = ', hrold
486          opass = .false.
487       END IF
488       
489       !  Check that the minute of NDATE makes sense.
490       
491       IF ((minew.GT.59).or.(minew.LT.0)) THEN
492          PRINT*, 'GETH_IDTS:  Minute of NDATE = ', minew
493          npass = .false.
494       END IF
495       
496       !  Check that the minute of ODATE makes sense.
497       
498       IF ((miold.GT.59).or.(miold.LT.0)) THEN
499          PRINT*, 'GETH_IDTS:  Minute of ODATE = ', miold
500          opass = .false.
501       END IF
502       
503       !  Check that the second of NDATE makes sense.
504       
505       IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
506          PRINT*, 'GETH_IDTS:  SECOND of NDATE = ', scnew
507          npass = .false.
508       END IF
509       
510       !  Check that the second of ODATE makes sense.
511       
512       IF ((scold.GT.59).or.(scold.LT.0)) THEN
513          PRINT*, 'GETH_IDTS:  Second of ODATE = ', scold
514          opass = .false.
515       END IF
516       
517       IF (.not. npass) THEN
518          PRINT*, 'Screwy NDATE: ', ndate(1:nlen)
519          STOP 'ndate_2'
520       END IF
521       
522       IF (.not. opass) THEN
523          PRINT*, 'Screwy ODATE: ', odate(1:olen)
524          STOP 'odate_1'
525       END IF
526       
527       !  Date Checks are completed.  Continue.
528       
529       !  Compute number of days from 1 January ODATE, 00:00:00 until ndate
530       !  Compute number of hours from 1 January ODATE, 00:00:00 until ndate
531       !  Compute number of minutes from 1 January ODATE, 00:00:00 until ndate
532       
533       newdys = 0
534       DO i = yrold, yrnew - 1
535          newdys = newdys + 365 + (nfeb(i)-28)
536       END DO
537       
538       IF (monew .GT. 1) THEN
539          mday(2) = nfeb(yrnew)
540          DO i = 1, monew - 1
541             newdys = newdys + mday(i)
542          END DO
543          mday(2) = 28
544       END IF
545       
546       newdys = newdys + dynew-1
547       
548       !  Compute number of hours from 1 January ODATE, 00:00:00 until odate
549       !  Compute number of minutes from 1 January ODATE, 00:00:00 until odate
550       
551       olddys = 0
552       
553       IF (moold .GT. 1) THEN
554          mday(2) = nfeb(yrold)
555          DO i = 1, moold - 1
556             olddys = olddys + mday(i)
557          END DO
558          mday(2) = 28
559       END IF
560       
561       olddys = olddys + dyold-1
562       
563       !  Determine the time difference in seconds
564       
565       idts = (newdys - olddys) * 86400
566       idts = idts + (hrnew - hrold) * 3600
567       idts = idts + (minew - miold) * 60
568       idts = idts + (scnew - scold)
569       
570       IF (isign .eq. -1) THEN
571          tdate=ndate
572          ndate=odate
573          odate=tdate
574          idts = idts * isign
575       END IF
576    
577    END SUBROUTINE geth_idts_old
579 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581    SUBROUTINE geth_newdate (ndate, odate, idt)
582    
583       IMPLICIT NONE
584       
585       !  From old date ('YYYY-MM-DD HH:MM:SS.ffff') and 
586       !  delta-time, compute the new date.
587    
588       !  on entry     -  odate  -  the old hdate.
589       !                  idt    -  the change in time
590    
591       !  on exit      -  ndate  -  the new hdate.
592       
593       INTEGER , INTENT(IN)           :: idt
594       CHARACTER (LEN=*) , INTENT(OUT) :: ndate
595       CHARACTER (LEN=*) , INTENT(IN)  :: odate
596       
597        
598       !  Local Variables
599        
600       !  yrold    -  indicates the year associated with "odate"
601       !  moold    -  indicates the month associated with "odate"
602       !  dyold    -  indicates the day associated with "odate"
603       !  hrold    -  indicates the hour associated with "odate"
604       !  miold    -  indicates the minute associated with "odate"
605       !  scold    -  indicates the second associated with "odate"
606        
607       !  yrnew    -  indicates the year associated with "ndate"
608       !  monew    -  indicates the month associated with "ndate"
609       !  dynew    -  indicates the day associated with "ndate"
610       !  hrnew    -  indicates the hour associated with "ndate"
611       !  minew    -  indicates the minute associated with "ndate"
612       !  scnew    -  indicates the second associated with "ndate"
613        
614       !  mday     -  a list assigning the number of days in each month
615       
616       !  i        -  loop counter
617       !  nday     -  the integer number of days represented by "idt"
618       !  nhour    -  the integer number of hours in "idt" after taking out
619       !              all the whole days
620       !  nmin     -  the integer number of minutes in "idt" after taking out
621       !              all the whole days and whole hours.
622       !  nsec     -  the integer number of minutes in "idt" after taking out
623       !              all the whole days, whole hours, and whole minutes.
624        
625       INTEGER :: nlen, olen
626       INTEGER :: yrnew, monew, dynew, hrnew, minew, scnew, frnew
627       INTEGER :: yrold, moold, dyold, hrold, miold, scold, frold
628       INTEGER :: mday(12), nday, nhour, nmin, nsec, nfrac, i, ifrc
629       LOGICAL :: opass
630       CHARACTER (LEN=10) :: hfrc
631       CHARACTER (LEN=1) :: sp
632       
633       !  Assign the number of days in a months
634       
635       mday( 1) = 31
636       mday( 2) = 28
637       mday( 3) = 31
638       mday( 4) = 30
639       mday( 5) = 31
640       mday( 6) = 30
641       mday( 7) = 31
642       mday( 8) = 31
643       mday( 9) = 30
644       mday(10) = 31
645       mday(11) = 30
646       mday(12) = 31
647       
648       !  Break down old hdate into parts
649       
650       hrold = 0
651       miold = 0
652       scold = 0
653       frold = 0
654       olen = LEN(odate)
655       IF (olen.GE.11) THEN
656          sp = odate(11:11)
657       else
658          sp = ' '
659       END IF
660       
661       !  Use internal READ statements to convert the CHARACTER string
662       !  date into INTEGER components.
663    
664       READ(odate(1:4),  '(I4)') yrold
665       READ(odate(6:7),  '(I2)') moold
666       READ(odate(9:10), '(I2)') dyold
667       IF (olen.GE.13) THEN
668          READ(odate(12:13),'(I2)') hrold
669          IF (olen.GE.16) THEN
670             READ(odate(15:16),'(I2)') miold
671             IF (olen.GE.19) THEN
672                READ(odate(18:19),'(I2)') scold
673                IF (olen.GT.20) THEN
674                   READ(odate(21:olen),'(I2)') frold
675                END IF
676             END IF
677          END IF
678       END IF
679       
680       !  Set the number of days in February for that year.
681       
682       mday(2) = nfeb(yrold)
683       
684       !  Check that ODATE makes sense.
685       
686       opass = .TRUE.
687       
688       !  Check that the month of ODATE makes sense.
689       
690       IF ((moold.GT.12).or.(moold.LT.1)) THEN
691          WRITE(*,*) 'GETH_NEWDATE:  Month of ODATE = ', moold
692          opass = .FALSE.
693       END IF
694       
695       !  Check that the day of ODATE makes sense.
696       
697       IF ((dyold.GT.mday(moold)).or.(dyold.LT.1)) THEN
698          WRITE(*,*) 'GETH_NEWDATE:  Day of ODATE = ', dyold
699          opass = .FALSE.
700       END IF
701       
702       !  Check that the hour of ODATE makes sense.
703       
704       IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
705          WRITE(*,*) 'GETH_NEWDATE:  Hour of ODATE = ', hrold
706          opass = .FALSE.
707       END IF
708       
709       !  Check that the minute of ODATE makes sense.
710       
711       IF ((miold.GT.59).or.(miold.LT.0)) THEN
712          WRITE(*,*) 'GETH_NEWDATE:  Minute of ODATE = ', miold
713          opass = .FALSE.
714       END IF
715       
716       !  Check that the second of ODATE makes sense.
717       
718       IF ((scold.GT.59).or.(scold.LT.0)) THEN
719          WRITE(*,*) 'GETH_NEWDATE:  Second of ODATE = ', scold
720          opass = .FALSE.
721       END IF
722       
723       !  Check that the fractional part  of ODATE makes sense.
724       
725       !KWM      IF ((scold.GT.59).or.(scold.LT.0)) THEN
726       !KWM         WRITE(*,*) 'GETH_NEWDATE:  Second of ODATE = ', scold
727       !KWM         opass = .FALSE.
728       !KWM      END IF
729       
730       IF (.not.opass) THEN
731          WRITE(*,*) 'GETH_NEWDATE: Crazy ODATE: ', odate(1:olen), olen
732          STOP 'odate_3'
733       END IF
734       
735       !  Date Checks are completed.  Continue.
736       
737       
738       !  Compute the number of days, hours, minutes, and seconds in idt
739       
740       IF (olen.GT.20) THEN !idt should be in fractions of seconds
741          ifrc = olen-20
742          ifrc = 10**ifrc
743          nday   = ABS(idt)/(86400*ifrc)
744          nhour  = MOD(ABS(idt),86400*ifrc)/(3600*ifrc)
745          nmin   = MOD(ABS(idt),3600*ifrc)/(60*ifrc)
746          nsec   = MOD(ABS(idt),60*ifrc)/(ifrc)
747          nfrac = MOD(ABS(idt), ifrc)
748       ELSE IF (olen.eq.19) THEN  !idt should be in seconds
749          ifrc = 1
750          nday   = ABS(idt)/86400 ! Integer number of days in delta-time
751          nhour  = MOD(ABS(idt),86400)/3600
752          nmin   = MOD(ABS(idt),3600)/60
753          nsec   = MOD(ABS(idt),60)
754          nfrac  = 0
755       ELSE IF (olen.eq.16) THEN !idt should be in minutes
756          ifrc = 1
757          nday   = ABS(idt)/1440 ! Integer number of days in delta-time
758          nhour  = MOD(ABS(idt),1440)/60
759          nmin   = MOD(ABS(idt),60)
760          nsec   = 0
761          nfrac  = 0
762       ELSE IF (olen.eq.13) THEN !idt should be in hours
763          ifrc = 1
764          nday   = ABS(idt)/24 ! Integer number of days in delta-time
765          nhour  = MOD(ABS(idt),24)
766          nmin   = 0
767          nsec   = 0
768          nfrac  = 0
769       ELSE IF (olen.eq.10) THEN !idt should be in days
770          ifrc = 1
771          nday   = ABS(idt)/24 ! Integer number of days in delta-time
772          nhour  = 0
773          nmin   = 0
774          nsec   = 0
775          nfrac  = 0
776       ELSE
777          WRITE(*,'(''GETH_NEWDATE: Strange length for ODATE: '', i3)') &
778               olen
779          WRITE(*,*) odate(1:olen)
780          STOP 'odate_4'
781       END IF
782       
783       IF (idt.GE.0) THEN
784       
785          frnew = frold + nfrac
786          IF (frnew.GE.ifrc) THEN
787             frnew = frnew - ifrc
788             nsec = nsec + 1
789          END IF
790       
791          scnew = scold + nsec
792          IF (scnew .GE. 60) THEN
793             scnew = scnew - 60
794             nmin  = nmin + 1
795          END IF
796       
797          minew = miold + nmin
798          IF (minew .GE. 60) THEN
799             minew = minew - 60
800             nhour  = nhour + 1
801          END IF
802       
803          hrnew = hrold + nhour
804          IF (hrnew .GE. 24) THEN
805             hrnew = hrnew - 24
806             nday  = nday + 1
807          END IF
808       
809          dynew = dyold
810          monew = moold
811          yrnew = yrold
812          DO i = 1, nday
813             dynew = dynew + 1
814             IF (dynew.GT.mday(monew)) THEN
815                dynew = dynew - mday(monew)
816                monew = monew + 1
817                IF (monew .GT. 12) THEN
818                   monew = 1
819                   yrnew = yrnew + 1
820                   ! If the year changes, recompute the number of days in February
821                   mday(2) = nfeb(yrnew)
822                END IF
823             END IF
824          END DO
825       
826       ELSE IF (idt.LT.0) THEN
827       
828          frnew = frold - nfrac
829          IF (frnew .LT. 0) THEN
830             frnew = frnew + ifrc
831             nsec = nsec - 1
832          END IF
833       
834          scnew = scold - nsec
835          IF (scnew .LT. 00) THEN
836             scnew = scnew + 60
837             nmin  = nmin + 1
838          END IF
839       
840          minew = miold - nmin
841          IF (minew .LT. 00) THEN
842             minew = minew + 60
843             nhour  = nhour + 1
844          END IF
845       
846          hrnew = hrold - nhour
847          IF (hrnew .LT. 00) THEN
848             hrnew = hrnew + 24
849             nday  = nday + 1
850          END IF
851       
852          dynew = dyold
853          monew = moold
854          yrnew = yrold
855          DO i = 1, nday
856             dynew = dynew - 1
857             IF (dynew.eq.0) THEN
858                monew = monew - 1
859                IF (monew.eq.0) THEN
860                   monew = 12
861                   yrnew = yrnew - 1
862                   ! If the year changes, recompute the number of days in February
863                   mday(2) = nfeb(yrnew)
864                END IF
865                dynew = mday(monew)
866             END IF
867          END DO
868       END IF
869       
870       !  Now construct the new mdate
871       
872       nlen = LEN(ndate)
873       
874       IF (nlen.GT.20) THEN
875          WRITE(ndate(1:19),19) yrnew, monew, dynew, hrnew, minew, scnew
876          WRITE(hfrc,'(I10)') frnew+1000000000
877          ndate = ndate(1:19)//'.'//hfrc(31-nlen:10)
878       
879       ELSE IF (nlen.eq.19.or.nlen.eq.20) THEN
880          WRITE(ndate(1:19),19) yrnew, monew, dynew, hrnew, minew, scnew
881       19   format(I4,'-',I2.2,'-',I2.2,'_',I2.2,':',I2.2,':',I2.2)
882          IF (nlen.eq.20) ndate = ndate(1:19)//'.'
883       
884       ELSE IF (nlen.eq.16) THEN
885          WRITE(ndate,16) yrnew, monew, dynew, hrnew, minew
886       16   format(I4,'-',I2.2,'-',I2.2,'_',I2.2,':',I2.2)
887       
888       ELSE IF (nlen.eq.13) THEN
889          WRITE(ndate,13) yrnew, monew, dynew, hrnew
890       13   format(I4,'-',I2.2,'-',I2.2,'_',I2.2)
891       
892       ELSE IF (nlen.eq.10) THEN
893          WRITE(ndate,10) yrnew, monew, dynew
894       10   format(I4,'-',I2.2,'-',I2.2)
895       
896       END IF
897       
898       IF (olen.GE.11) ndate(11:11) = sp
899    
900    END SUBROUTINE geth_newdate
902 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
904    FUNCTION nfeb ( year ) RESULT (num_days)
905    
906       ! Compute the number of days in February for the given year
907    
908       IMPLICIT NONE
909    
910       INTEGER :: year
911       INTEGER :: num_days
912    
913       num_days = 28 ! By default, February has 28 days ...
914       IF (MOD(year,4).eq.0) THEN  
915          num_days = 29  ! But every four years, it has 29 days ...
916          IF (MOD(year,100).eq.0) THEN
917             num_days = 28  ! Except every 100 years, when it has 28 days ...
918             IF (MOD(year,400).eq.0) THEN
919                num_days = 29  ! Except every 400 years, when it has 29 days.
920             END IF
921          END IF
922       END IF
923    
924    END FUNCTION nfeb
927 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
929    FUNCTION nfeb_ch ( year_ch ) RESULT (num_days_ch)
930    
931       ! Compute the number of days in February for the given year
932    
933       IMPLICIT NONE
934    
935       INTEGER :: year , num_days
936       CHARACTER(LEN=4) :: year_ch
937       CHARACTER(LEN=2) :: num_days_ch
939       READ ( year_ch , '(I4.4)' ) year
940    
941       num_days = 28 ! By default, February has 28 days ...
942       IF (MOD(year,4).eq.0) THEN  
943          num_days = 29  ! But every four years, it has 29 days ...
944          IF (MOD(year,100).eq.0) THEN
945             num_days = 28  ! Except every 100 years, when it has 28 days ...
946             IF (MOD(year,400).eq.0) THEN
947                num_days = 29  ! Except every 400 years, when it has 29 days.
948             END IF
949          END IF
950       END IF
952       WRITE ( num_days_ch , '(I2.2)' ) num_days
953    
954    END FUNCTION nfeb_ch
956 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
958    SUBROUTINE split_date_char ( date , century_year , month , day , hour , minute , second )
959      
960       IMPLICIT NONE
961    
962       !  Input data.
963    
964       CHARACTER(LEN=19) , INTENT(IN) :: date 
965    
966       !  Output data.
967    
968       INTEGER , INTENT(OUT) :: century_year , month , day , hour , minute , second
969       
970       READ(date,FMT='(    I4.4)') century_year
971       READ(date,FMT='( 5X,I2.2)') month
972       READ(date,FMT='( 8X,I2.2)') day
973       READ(date,FMT='(11X,I2.2)') hour
974       READ(date,FMT='(14X,I2.2)') minute
975       READ(date,FMT='(17X,I2.2)') second
976    
977    END SUBROUTINE split_date_char
978    
979 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
981       SUBROUTINE gather_date_char ( date, century_year , month , day , &
982                                     hour, minute, second )
984       IMPLICIT NONE
986       !  Input data.
988       INTEGER , INTENT(IN) :: century_year , month , day , &
989                                hour , minute , second
991       !  Output data.
993       CHARACTER(LEN=19) , INTENT(OUT) :: date
994       WRITE (DATE,FMT = '(I4.4,"-",I2.2,"-",I2.2,"_",I2.2,":",I2.2,":",I2.2)')&
995       century_year,month,day,hour,minute,second
997 END SUBROUTINE gather_date_char
999 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1001 SUBROUTINE make_date ( date , time , date_time_char )
1003 !  This routine takes an 8-digit date (YYYYMMDD) and a
1004 !  6-digit time (HHmmss) and converts it to a 24-digit
1005 !  string (YYYY-MM-DD_HH:mm:ss.ffff).
1007    INTEGER , INTENT(IN) :: date , &
1008                            time
1010    CHARACTER (LEN=24) , INTENT(OUT) :: date_time_char
1013    !  Local data.
1015    INTEGER :: year , month , day , hour , minute , second , fraction
1017    year = date / 10000
1018    month = ( date - year*10000 ) / 100
1019    day   =  date - year*10000 - month*100
1022    hour = time / 10000
1023    minute = ( time - hour*10000 ) / 100
1024    second = time - hour*10000 - minute*100
1026    fraction = 0
1028    WRITE ( date_time_char , &
1029    FMT = '(I4.4,"-",I2.2,"-",I2.2,"_",I2.2,":",I2.2,":",I2.2,".",I4.4) ') &
1030            year , month ,    day ,    hour  , minute , second , fraction
1032 END SUBROUTINE make_date
1034 SUBROUTINE Julian_DAY(NY,NM,ND,JD,METHOD)                                       
1035 !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC        
1036 !                                                                      C        
1037 !   METHOD = 1: INPUT ---- NY, NM, ND.  OUTPUT ---- JD                 C        
1038 !   METHOD = 2: INPUT ---- NY, JD.      OUTPUT ---- NM, ND             C        
1039 !                                                                      C        
1040 !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC        
1041 IMPLICIT NONE
1043 integer, DIMENSION(12)  :: MDAY = (/31,28,31,30,31,30,31,31,30,31,30,31/)
1045 integer,  intent(IN)    :: METHOD
1046 integer,  intent(INOUT) :: NY, NM, ND, JD
1047                                                                                 
1048 integer      :: JDLEFT, JDSOFAR, LOOP
1049       IF(METHOD.EQ.1) THEN                                                      
1050          JD=0                                                                   
1051          IF(MOD(NY,4).EQ.0) MDAY(2)=29                                          
1052    JuDAY:DO LOOP=1,NM-1                                                      
1053           JD=JD+MDAY(LOOP)                                                    
1054          ENDDO JuDAY                                                               
1055          JD=JD+ND                                                               
1057       ELSE IF(METHOD.EQ.2) THEN                                                 
1058          IF(MOD(NY,4).EQ.0) MDAY(2)=29                                          
1059          NM=1                                                                   
1060          ND=0                                                                   
1061          JDLEFT=JD                                                              
1062          JDSOFAR=0                                                              
1063    NYEAR:DO LOOP=1,11                                                        
1064           IF(JDLEFT.GT.MDAY(LOOP)) THEN                                       
1065              JDLEFT=JDLEFT-MDAY(LOOP)                                         
1066              JDSOFAR=JDSOFAR+MDAY(LOOP)                                       
1067              NM=NM+1                                                          
1068              CYCLE NYEAR                                                          
1069           END IF                                                              
1070           EXIT NYEAR                                                             
1071          ENDDO NYEAR                                                               
1072          ND=JDLEFT                                                              
1073       END IF                                                                    
1075 END subroutine Julian_DAY
1077 subroutine Sec_to_hhmmss(hh,mm,ss,seconds,method)
1079 !  Conversion of hh,mm,ss to seconds (method=1) or
1080 !                seconds to hh,mm,ss (method=2).
1081 !    
1083   implicit none
1085   integer,   intent(in)    :: method
1086   integer,   intent(inout) :: hh, mm, ss, seconds
1088   integer                  :: zz
1090   if (method == 1) then
1091     seconds = hh*3600 + mm*60 + ss
1092   else if (method == 2) then
1093     hh = int(seconds/3600.)
1094     zz = seconds - hh*3600
1095     mm = int(zz/60.)
1096     ss = zz - mm*60
1097     if (mm > 58) then
1098       mm = 0
1099       ss = 0 
1100       hh = hh + 1
1101     endif
1102   else
1103     write(0,'(''Method ='',I3,'' is invalid'')') method
1104   endif
1106 end subroutine Sec_to_hhmmss
1108 SUBROUTINE get_month (pmm,cdmm)
1110       INTEGER             :: pmm
1111       CHARACTER (LEN = *) :: cdmm
1113       SELECT CASE (PMM)
1115       CASE ( 1) ;    cdmm = 'JANUARY'
1116       CASE ( 2) ;    cdmm = 'FEBRUARY'
1117       CASE ( 3) ;    cdmm = 'MARCH'
1118       CASE ( 4) ;    cdmm = 'APRIL'
1119       CASE ( 5) ;    cdmm = 'MAY'
1120       CASE ( 6) ;    cdmm = 'JUNE'
1121       CASE ( 7) ;    cdmm = 'JULY'
1122       CASE ( 8) ;    cdmm = 'AUGUST'
1123       CASE ( 9) ;    cdmm = 'SEPTEMBER'
1124       CASE (10) ;    cdmm = 'OCTOBER'
1125       CASE (11) ;    cdmm = 'NOVEMBER'
1126       CASE (12) ;    cdmm = 'DECEMBER'
1127       CASE DEFAULT ; cdmm = 'UNKNOWN'
1129       END SELECT
1131 END SUBROUTINE get_month
1133 SUBROUTINE geth_idts_2 (ndate, odate, idts, pass, iunit)
1134    
1135       IMPLICIT NONE
1136       
1137       !  From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'), 
1138       !  compute the time difference.
1139       
1140       !  on entry     -  ndate  -  the new hdate.
1141       !                  odate  -  the old hdate.
1142       !  on entry     -  iunit   -  logical unit to output error messages
1143       
1144       !  on exit      -  idts    -  the change in time in seconds.
1145       !  on exit      -  pass    -  False if input sting is not a date
1146       
1147       CHARACTER (LEN=*) , INTENT(IN) :: ndate, odate
1148       INTEGER           , INTENT(OUT)   :: idts
1149       LOGICAL, OPTIONAL                 :: pass
1150       INTEGER, OPTIONAL                 :: iunit
1152       !  Local Variables
1153       
1154       !  yrnew    -  indicates the year associated with "ndate"
1155       !  yrold    -  indicates the year associated with "odate"
1156       !  monew    -  indicates the month associated with "ndate"
1157       !  moold    -  indicates the month associated with "odate"
1158       !  dynew    -  indicates the day associated with "ndate"
1159       !  dyold    -  indicates the day associated with "odate"
1160       !  hrnew    -  indicates the hour associated with "ndate"
1161       !  hrold    -  indicates the hour associated with "odate"
1162       !  minew    -  indicates the minute associated with "ndate"
1163       !  miold    -  indicates the minute associated with "odate"
1164       !  scnew    -  indicates the second associated with "ndate"
1165       !  scold    -  indicates the second associated with "odate"
1166       !  i        -  loop counter
1167       !  mday     -  a list assigning the number of days in each month
1168       !  iout     -  logical unit to output error messages (default 0)
1169       
1170       CHARACTER (LEN=24) :: tdate, lndate, lodate
1171       INTEGER :: olen, nlen
1172       INTEGER :: yrnew, monew, dynew, hrnew, minew, scnew
1173       INTEGER :: yrold, moold, dyold, hrold, miold, scold
1174       INTEGER :: mday(12), i, newdys, olddys
1175       LOGICAL :: npass, opass
1176       INTEGER :: isign, iout
1178       lndate = ndate
1179       lodate = odate
1180       IF (odate.GT.ndate) THEN
1181          isign = -1
1182          tdate=ndate
1183          lndate=lodate
1184          lodate=tdate
1185       ELSE
1186          isign = 1
1187       END IF
1188       
1189       !  Assign the number of days in a months
1190       
1191       mday( 1) = 31
1192       mday( 2) = 28
1193       mday( 3) = 31
1194       mday( 4) = 30
1195       mday( 5) = 31
1196       mday( 6) = 30
1197       mday( 7) = 31
1198       mday( 8) = 31
1199       mday( 9) = 30
1200       mday(10) = 31
1201       mday(11) = 30
1202       mday(12) = 31
1203       
1204       !  Break down old hdate into parts
1205       
1206       hrold = 0
1207       miold = 0
1208       scold = 0
1209       olen = LEN(lodate)
1210       
1211       READ(odate(1:4),  '(I4)') yrold
1212       READ(odate(6:7),  '(I2)') moold
1213       READ(odate(9:10), '(I2)') dyold
1214       IF (olen.GE.13) THEN
1215          READ(odate(12:13),'(I2)') hrold
1216          IF (olen.GE.16) THEN
1217             READ(odate(15:16),'(I2)') miold
1218             IF (olen.GE.19) THEN
1219                READ(odate(18:19),'(I2)') scold
1220             END IF
1221          END IF
1222       END IF
1223       
1224       !  Break down new hdate into parts
1225       
1226       hrnew = 0
1227       minew = 0
1228       scnew = 0
1229       nlen = LEN(lndate)
1231       READ(ndate(1:4),  '(I4)') yrnew
1232       READ(ndate(6:7),  '(I2)') monew
1233       READ(ndate(9:10), '(I2)') dynew
1234       IF (nlen.GE.13) THEN
1235          READ(ndate(12:13),'(I2)') hrnew
1236          IF (nlen.GE.16) THEN
1237             READ(ndate(15:16),'(I2)') minew
1238             IF (nlen.GE.19) THEN
1239                READ(ndate(18:19),'(I2)') scnew
1240             END IF
1241          END IF
1242       END IF
1243       
1244       !  Check that the dates make sense.
1245       
1246       npass = .true.
1247       opass = .true.
1249       iout = 0
1250       IF (PRESENT (pass))  &
1251           pass = .true.
1252       IF (PRESENT (iunit)) &
1253           iout =  iunit
1254       
1255       !  Check that the month of NDATE makes sense.
1256       
1257       IF ((monew.GT.12).or.(monew.LT.1)) THEN
1258          WRITE (iout,'(A,A)') ' GETH_IDTS:  Month of NDATE = ', monew
1259          npass = .false.
1260       END IF
1261       
1262       !  Check that the month of ODATE makes sense.
1263       
1264       IF ((moold.GT.12).or.(moold.LT.1)) THEN
1265          WRITE (iout,'(A,I2)') ' GETH_IDTS:  Month of ODATE = ', moold
1266          opass = .false.
1267       END IF
1268       
1269       !  Check that the day of NDATE makes sense.
1270       
1271       IF (monew.ne.2) THEN
1272       ! ...... For all months but February
1273          IF ((dynew.GT.mday(monew)).or.(dynew.LT.1)) THEN
1274 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of NDATE = ', dynew
1275             npass = .false.
1276          END IF
1277       ELSE IF (monew.eq.2) THEN
1278       ! ...... For February
1279          IF ((dynew.GT.nfeb(yrnew)).or.(dynew.LT.1)) THEN
1280 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of NDATE = ', dynew
1281             npass = .false.
1282          END IF
1283       END IF
1284       
1285       !  Check that the day of ODATE makes sense.
1286       
1287       IF (moold.ne.2) THEN
1288       ! ...... For all months but February
1289          IF ((dyold.GT.mday(moold)).OR.(dyold.LT.1)) THEN
1290 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of ODATE = ', dyold
1291             opass = .false.
1292          END IF
1293       ELSE IF (moold.eq.2) THEN
1294       ! ....... For February
1295          IF ((dyold.GT.nfeb(yrold)).OR.(dyold.LT.1)) THEN
1296 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Day of ODATE = ', dyold
1297             opass = .false.
1298          END IF
1299       END IF
1300       
1301       !  Check that the hour of NDATE makes sense.
1302       
1303       IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
1304 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Hour of NDATE = ', hrnew
1305          npass = .false.
1306       END IF
1307       
1308       !  Check that the hour of ODATE makes sense.
1309       
1310       IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
1311 !           WRITE (iout,'(A,I2)') ' GETH_IDTS:  Hour of ODATE = ', hrold
1312          opass = .false.
1313       END IF
1314       
1315       !  Check that the minute of NDATE makes sense.
1316       
1317       IF ((minew.GT.59).or.(minew.LT.0)) THEN
1318             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Minute of NDATE = ', minew
1319          npass = .false.
1320       END IF
1321       
1322       !  Check that the minute of ODATE makes sense.
1323       
1324       IF ((miold.GT.59).or.(miold.LT.0)) THEN
1325             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Minute of ODATE = ', miold
1326          opass = .false.
1327       END IF
1328       
1329       !  Check that the second of NDATE makes sense.
1330       
1331       IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
1332             WRITE (iout,'(A,I2)') ' GETH_IDTS:  SECOND of NDATE = ', scnew
1333          npass = .false.
1334       END IF
1335       
1336       !  Check that the second of ODATE makes sense.
1337       
1338       IF ((scold.GT.59).or.(scold.LT.0)) THEN
1339             WRITE (iout,'(A,I2)') ' GETH_IDTS:  Second of ODATE = ', scold
1340          opass = .false.
1341       END IF
1342       
1343       IF (.not. npass) THEN
1344          IF (PRESENT (pass)) THEN
1345              idts = 0
1346              pass = .false.
1347              WRITE (iout,'(A,A)') 'Screwy NDATE: ', lndate(1:nlen)
1348              IF (isign == -1) THEN
1349                  tdate=ndate
1350                  lndate=lodate
1351                  lodate=tdate
1352              ENDIF
1353              RETURN
1354          ELSE
1355              STOP 'ndate_2'
1356          ENDIF
1357       END IF
1358       
1359       IF (.not. opass) THEN
1360          IF (PRESENT (pass)) THEN
1361              idts = 0
1362              pass = .false.
1363              WRITE (iout,'(A,A)') 'Screwy ODATE: ', odate(1:nlen)
1364              IF (isign == -1) THEN
1365                  tdate=lndate
1366                  lndate=lodate
1367                  lodate=tdate
1368              ENDIF
1369              RETURN
1370          ELSE
1371              STOP 'odate_1'
1372          ENDIF
1373       END IF
1374       
1375       !  Date Checks are completed.  Continue.
1376       
1377       !  Compute number of days from 1 January ODATE, 00:00:00 until ndate
1378       !  Compute number of hours from 1 January ODATE, 00:00:00 until ndate
1379       !  Compute number of minutes from 1 January ODATE, 00:00:00 until ndate
1380       
1381       newdys = 0
1382       DO i = yrold, yrnew - 1
1383          newdys = newdys + 365 + (nfeb(i)-28)
1384       END DO
1385       
1386       IF (monew .GT. 1) THEN
1387          mday(2) = nfeb(yrnew)
1388          DO i = 1, monew - 1
1389             newdys = newdys + mday(i)
1390          END DO
1391          mday(2) = 28
1392       END IF
1393       
1394       newdys = newdys + dynew-1
1395       
1396       !  Compute number of hours from 1 January ODATE, 00:00:00 until odate
1397       !  Compute number of minutes from 1 January ODATE, 00:00:00 until odate
1398       
1399       olddys = 0
1400       
1401       IF (moold .GT. 1) THEN
1402          mday(2) = nfeb(yrold)
1403          DO i = 1, moold - 1
1404             olddys = olddys + mday(i)
1405          END DO
1406          mday(2) = 28
1407       END IF
1408       
1409       olddys = olddys + dyold-1
1410       
1411       !  Determine the time difference in seconds
1412       
1413       idts = (newdys - olddys) * 86400
1414       idts = idts + (hrnew - hrold) * 3600
1415       idts = idts + (minew - miold) * 60
1416       idts = idts + (scnew - scold)
1417       
1418       IF (isign .eq. -1) THEN
1419          tdate=lndate
1420          lndate=lodate
1421          lodate=tdate
1422          idts = idts * isign
1423       END IF
1424    
1425    END SUBROUTINE geth_idts_2
1427 END MODULE module_date