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.
24 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
26 SUBROUTINE geth_idts (ndate, odate, idts, pass, iunit)
30 ! From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'),
31 ! compute the time difference.
33 ! on entry - ndate - the new hdate.
34 ! odate - the old hdate.
35 ! on entry - iunit - logical unit to output error messages
37 ! on exit - idts - the change in time in seconds.
38 ! on exit - pass - False if input sting is not a date
40 CHARACTER (LEN=*) , INTENT(INOUT) :: ndate, odate
41 INTEGER , INTENT(OUT) :: idts
42 LOGICAL, OPTIONAL :: pass
43 INTEGER, OPTIONAL :: iunit
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"
60 ! mday - a list assigning the number of days in each month
61 ! iout - logical unit to output error messages (default 0)
63 CHARACTER (LEN=24) :: tdate
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
80 ! Assign the number of days in a months
95 ! Break down old hdate into parts
102 READ(odate(1:4), '(I4)') yrold
103 READ(odate(6:7), '(I2)') moold
104 READ(odate(9:10), '(I2)') dyold
106 READ(odate(12:13),'(I2)') hrold
108 READ(odate(15:16),'(I2)') miold
110 READ(odate(18:19),'(I2)') scold
115 ! Break down new hdate into parts
122 READ(ndate(1:4), '(I4)') yrnew
123 READ(ndate(6:7), '(I2)') monew
124 READ(ndate(9:10), '(I2)') dynew
126 READ(ndate(12:13),'(I2)') hrnew
128 READ(ndate(15:16),'(I2)') minew
130 READ(ndate(18:19),'(I2)') scnew
135 ! Check that the dates make sense.
141 IF (PRESENT (pass)) &
143 IF (PRESENT (iunit)) &
146 ! Check that the month of NDATE makes sense.
148 IF ((monew.GT.12).or.(monew.LT.1)) THEN
149 WRITE (iout,'(A,A)') ' GETH_IDTS: Month of NDATE = ', monew
153 ! Check that the month of ODATE makes sense.
155 IF ((moold.GT.12).or.(moold.LT.1)) THEN
156 WRITE (iout,'(A,I2)') ' GETH_IDTS: Month of ODATE = ', moold
160 ! Check that the day of NDATE makes sense.
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
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
176 ! Check that the day of ODATE makes sense.
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
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
192 ! Check that the hour of NDATE makes sense.
194 IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
195 ! WRITE (iout,'(A,I2)') ' GETH_IDTS: Hour of NDATE = ', hrnew
199 ! Check that the hour of ODATE makes sense.
201 IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
202 ! WRITE (iout,'(A,I2)') ' GETH_IDTS: Hour of ODATE = ', hrold
206 ! Check that the minute of NDATE makes sense.
208 IF ((minew.GT.59).or.(minew.LT.0)) THEN
209 WRITE (iout,'(A,I2)') ' GETH_IDTS: Minute of NDATE = ', minew
213 ! Check that the minute of ODATE makes sense.
215 IF ((miold.GT.59).or.(miold.LT.0)) THEN
216 WRITE (iout,'(A,I2)') ' GETH_IDTS: Minute of ODATE = ', miold
220 ! Check that the second of NDATE makes sense.
222 IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
223 WRITE (iout,'(A,I2)') ' GETH_IDTS: SECOND of NDATE = ', scnew
227 ! Check that the second of ODATE makes sense.
229 IF ((scold.GT.59).or.(scold.LT.0)) THEN
230 WRITE (iout,'(A,I2)') ' GETH_IDTS: Second of ODATE = ', scold
234 IF (.not. npass) THEN
235 IF (PRESENT (pass)) THEN
238 WRITE (iout,'(A,A)') 'Screwy NDATE: ', ndate(1:nlen)
239 IF (isign == -1) THEN
250 IF (.not. opass) THEN
251 IF (PRESENT (pass)) THEN
254 WRITE (iout,'(A,A)') 'Screwy ODATE: ', odate(1:nlen)
255 IF (isign == -1) THEN
266 ! Date Checks are completed. Continue.
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
273 DO i = yrold, yrnew - 1
274 newdys = newdys + 365 + (nfeb(i)-28)
277 IF (monew .GT. 1) THEN
278 mday(2) = nfeb(yrnew)
280 newdys = newdys + mday(i)
285 newdys = newdys + dynew-1
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
292 IF (moold .GT. 1) THEN
293 mday(2) = nfeb(yrold)
295 olddys = olddys + mday(i)
300 olddys = olddys + dyold-1
302 ! Determine the time difference in seconds
304 idts = (newdys - olddys) * 86400
305 idts = idts + (hrnew - hrold) * 3600
306 idts = idts + (minew - miold) * 60
307 idts = idts + (scnew - scold)
309 IF (isign .eq. -1) THEN
316 END SUBROUTINE geth_idts
318 !------------------------------------------------------------------------------!
320 SUBROUTINE geth_idts_old (ndate, odate, idts)
324 ! From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'),
325 ! compute the time difference.
327 ! on entry - ndate - the new hdate.
328 ! odate - the old hdate.
330 ! on exit - idts - the change in time in seconds.
332 CHARACTER (LEN=*) , INTENT(INOUT) :: ndate, odate
333 INTEGER , INTENT(OUT) :: idts
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"
350 ! mday - a list assigning the number of days in each month
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
360 IF (odate.GT.ndate) THEN
369 ! Assign the number of days in a months
384 ! Break down old hdate into parts
391 READ(odate(1:4), '(I4)') yrold
392 READ(odate(6:7), '(I2)') moold
393 READ(odate(9:10), '(I2)') dyold
395 READ(odate(12:13),'(I2)') hrold
397 READ(odate(15:16),'(I2)') miold
399 READ(odate(18:19),'(I2)') scold
404 ! Break down new hdate into parts
411 READ(ndate(1:4), '(I4)') yrnew
412 READ(ndate(6:7), '(I2)') monew
413 READ(ndate(9:10), '(I2)') dynew
415 READ(ndate(12:13),'(I2)') hrnew
417 READ(ndate(15:16),'(I2)') minew
419 READ(ndate(18:19),'(I2)') scnew
424 ! Check that the dates make sense.
429 ! Check that the month of NDATE makes sense.
431 IF ((monew.GT.12).or.(monew.LT.1)) THEN
432 PRINT*, 'GETH_IDTS: Month of NDATE = ', monew
436 ! Check that the month of ODATE makes sense.
438 IF ((moold.GT.12).or.(moold.LT.1)) THEN
439 PRINT*, 'GETH_IDTS: Month of ODATE = ', moold
443 ! Check that the day of NDATE makes sense.
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
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
459 ! Check that the day of ODATE makes sense.
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
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
475 ! Check that the hour of NDATE makes sense.
477 IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
478 PRINT*, 'GETH_IDTS: Hour of NDATE = ', hrnew
482 ! Check that the hour of ODATE makes sense.
484 IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
485 PRINT*, 'GETH_IDTS: Hour of ODATE = ', hrold
489 ! Check that the minute of NDATE makes sense.
491 IF ((minew.GT.59).or.(minew.LT.0)) THEN
492 PRINT*, 'GETH_IDTS: Minute of NDATE = ', minew
496 ! Check that the minute of ODATE makes sense.
498 IF ((miold.GT.59).or.(miold.LT.0)) THEN
499 PRINT*, 'GETH_IDTS: Minute of ODATE = ', miold
503 ! Check that the second of NDATE makes sense.
505 IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
506 PRINT*, 'GETH_IDTS: SECOND of NDATE = ', scnew
510 ! Check that the second of ODATE makes sense.
512 IF ((scold.GT.59).or.(scold.LT.0)) THEN
513 PRINT*, 'GETH_IDTS: Second of ODATE = ', scold
517 IF (.not. npass) THEN
518 PRINT*, 'Screwy NDATE: ', ndate(1:nlen)
522 IF (.not. opass) THEN
523 PRINT*, 'Screwy ODATE: ', odate(1:olen)
527 ! Date Checks are completed. Continue.
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
534 DO i = yrold, yrnew - 1
535 newdys = newdys + 365 + (nfeb(i)-28)
538 IF (monew .GT. 1) THEN
539 mday(2) = nfeb(yrnew)
541 newdys = newdys + mday(i)
546 newdys = newdys + dynew-1
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
553 IF (moold .GT. 1) THEN
554 mday(2) = nfeb(yrold)
556 olddys = olddys + mday(i)
561 olddys = olddys + dyold-1
563 ! Determine the time difference in seconds
565 idts = (newdys - olddys) * 86400
566 idts = idts + (hrnew - hrold) * 3600
567 idts = idts + (minew - miold) * 60
568 idts = idts + (scnew - scold)
570 IF (isign .eq. -1) THEN
577 END SUBROUTINE geth_idts_old
579 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
581 SUBROUTINE geth_newdate (ndate, odate, idt)
585 ! From old date ('YYYY-MM-DD HH:MM:SS.ffff') and
586 ! delta-time, compute the new date.
588 ! on entry - odate - the old hdate.
589 ! idt - the change in time
591 ! on exit - ndate - the new hdate.
593 INTEGER , INTENT(IN) :: idt
594 CHARACTER (LEN=*) , INTENT(OUT) :: ndate
595 CHARACTER (LEN=*) , INTENT(IN) :: odate
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"
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"
614 ! mday - a list assigning the number of days in each month
617 ! nday - the integer number of days represented by "idt"
618 ! nhour - the integer number of hours in "idt" after taking out
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.
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
630 CHARACTER (LEN=10) :: hfrc
631 CHARACTER (LEN=1) :: sp
633 ! Assign the number of days in a months
648 ! Break down old hdate into parts
661 ! Use internal READ statements to convert the CHARACTER string
662 ! date into INTEGER components.
664 READ(odate(1:4), '(I4)') yrold
665 READ(odate(6:7), '(I2)') moold
666 READ(odate(9:10), '(I2)') dyold
668 READ(odate(12:13),'(I2)') hrold
670 READ(odate(15:16),'(I2)') miold
672 READ(odate(18:19),'(I2)') scold
674 READ(odate(21:olen),'(I2)') frold
680 ! Set the number of days in February for that year.
682 mday(2) = nfeb(yrold)
684 ! Check that ODATE makes sense.
688 ! Check that the month of ODATE makes sense.
690 IF ((moold.GT.12).or.(moold.LT.1)) THEN
691 WRITE(*,*) 'GETH_NEWDATE: Month of ODATE = ', moold
695 ! Check that the day of ODATE makes sense.
697 IF ((dyold.GT.mday(moold)).or.(dyold.LT.1)) THEN
698 WRITE(*,*) 'GETH_NEWDATE: Day of ODATE = ', dyold
702 ! Check that the hour of ODATE makes sense.
704 IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
705 WRITE(*,*) 'GETH_NEWDATE: Hour of ODATE = ', hrold
709 ! Check that the minute of ODATE makes sense.
711 IF ((miold.GT.59).or.(miold.LT.0)) THEN
712 WRITE(*,*) 'GETH_NEWDATE: Minute of ODATE = ', miold
716 ! Check that the second of ODATE makes sense.
718 IF ((scold.GT.59).or.(scold.LT.0)) THEN
719 WRITE(*,*) 'GETH_NEWDATE: Second of ODATE = ', scold
723 ! Check that the fractional part of ODATE makes sense.
725 !KWM IF ((scold.GT.59).or.(scold.LT.0)) THEN
726 !KWM WRITE(*,*) 'GETH_NEWDATE: Second of ODATE = ', scold
731 WRITE(*,*) 'GETH_NEWDATE: Crazy ODATE: ', odate(1:olen), olen
735 ! Date Checks are completed. Continue.
738 ! Compute the number of days, hours, minutes, and seconds in idt
740 IF (olen.GT.20) THEN !idt should be in fractions of seconds
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
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)
755 ELSE IF (olen.eq.16) THEN !idt should be in minutes
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)
762 ELSE IF (olen.eq.13) THEN !idt should be in hours
764 nday = ABS(idt)/24 ! Integer number of days in delta-time
765 nhour = MOD(ABS(idt),24)
769 ELSE IF (olen.eq.10) THEN !idt should be in days
771 nday = ABS(idt)/24 ! Integer number of days in delta-time
777 WRITE(*,'(''GETH_NEWDATE: Strange length for ODATE: '', i3)') &
779 WRITE(*,*) odate(1:olen)
785 frnew = frold + nfrac
786 IF (frnew.GE.ifrc) THEN
792 IF (scnew .GE. 60) THEN
798 IF (minew .GE. 60) THEN
803 hrnew = hrold + nhour
804 IF (hrnew .GE. 24) THEN
814 IF (dynew.GT.mday(monew)) THEN
815 dynew = dynew - mday(monew)
817 IF (monew .GT. 12) THEN
820 ! If the year changes, recompute the number of days in February
821 mday(2) = nfeb(yrnew)
826 ELSE IF (idt.LT.0) THEN
828 frnew = frold - nfrac
829 IF (frnew .LT. 0) THEN
835 IF (scnew .LT. 00) THEN
841 IF (minew .LT. 00) THEN
846 hrnew = hrold - nhour
847 IF (hrnew .LT. 00) THEN
862 ! If the year changes, recompute the number of days in February
863 mday(2) = nfeb(yrnew)
870 ! Now construct the new mdate
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)
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)//'.'
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)
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)
892 ELSE IF (nlen.eq.10) THEN
893 WRITE(ndate,10) yrnew, monew, dynew
894 10 format(I4,'-',I2.2,'-',I2.2)
898 IF (olen.GE.11) ndate(11:11) = sp
900 END SUBROUTINE geth_newdate
902 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
904 FUNCTION nfeb ( year ) RESULT (num_days)
906 ! Compute the number of days in February for the given year
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.
927 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
929 FUNCTION nfeb_ch ( year_ch ) RESULT (num_days_ch)
931 ! Compute the number of days in February for the given year
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
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.
952 WRITE ( num_days_ch , '(I2.2)' ) num_days
956 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
958 SUBROUTINE split_date_char ( date , century_year , month , day , hour , minute , second )
964 CHARACTER(LEN=19) , INTENT(IN) :: date
968 INTEGER , INTENT(OUT) :: century_year , month , day , hour , minute , second
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
977 END SUBROUTINE split_date_char
979 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
981 SUBROUTINE gather_date_char ( date, century_year , month , day , &
982 hour, minute, second )
988 INTEGER , INTENT(IN) :: century_year , month , day , &
989 hour , minute , second
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 , &
1010 CHARACTER (LEN=24) , INTENT(OUT) :: date_time_char
1015 INTEGER :: year , month , day , hour , minute , second , fraction
1018 month = ( date - year*10000 ) / 100
1019 day = date - year*10000 - month*100
1023 minute = ( time - hour*10000 ) / 100
1024 second = time - hour*10000 - minute*100
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
1037 ! METHOD = 1: INPUT ---- NY, NM, ND. OUTPUT ---- JD C
1038 ! METHOD = 2: INPUT ---- NY, JD. OUTPUT ---- NM, ND C
1040 !CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
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
1048 integer :: JDLEFT, JDSOFAR, LOOP
1049 IF(METHOD.EQ.1) THEN
1051 IF(MOD(NY,4).EQ.0) MDAY(2)=29
1052 JuDAY:DO LOOP=1,NM-1
1057 ELSE IF(METHOD.EQ.2) THEN
1058 IF(MOD(NY,4).EQ.0) MDAY(2)=29
1064 IF(JDLEFT.GT.MDAY(LOOP)) THEN
1065 JDLEFT=JDLEFT-MDAY(LOOP)
1066 JDSOFAR=JDSOFAR+MDAY(LOOP)
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).
1085 integer, intent(in) :: method
1086 integer, intent(inout) :: hh, mm, ss, seconds
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
1103 write(0,'(''Method ='',I3,'' is invalid'')') method
1106 end subroutine Sec_to_hhmmss
1108 SUBROUTINE get_month (pmm,cdmm)
1111 CHARACTER (LEN = *) :: cdmm
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'
1131 END SUBROUTINE get_month
1133 SUBROUTINE geth_idts_2 (ndate, odate, idts, pass, iunit)
1137 ! From 2 input mdates ('YYYY-MM-DD HH:MM:SS.ffff'),
1138 ! compute the time difference.
1140 ! on entry - ndate - the new hdate.
1141 ! odate - the old hdate.
1142 ! on entry - iunit - logical unit to output error messages
1144 ! on exit - idts - the change in time in seconds.
1145 ! on exit - pass - False if input sting is not a date
1147 CHARACTER (LEN=*) , INTENT(IN) :: ndate, odate
1148 INTEGER , INTENT(OUT) :: idts
1149 LOGICAL, OPTIONAL :: pass
1150 INTEGER, OPTIONAL :: iunit
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"
1167 ! mday - a list assigning the number of days in each month
1168 ! iout - logical unit to output error messages (default 0)
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
1180 IF (odate.GT.ndate) THEN
1189 ! Assign the number of days in a months
1204 ! Break down old hdate into parts
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
1224 ! Break down new hdate into parts
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
1244 ! Check that the dates make sense.
1250 IF (PRESENT (pass)) &
1252 IF (PRESENT (iunit)) &
1255 ! Check that the month of NDATE makes sense.
1257 IF ((monew.GT.12).or.(monew.LT.1)) THEN
1258 WRITE (iout,'(A,A)') ' GETH_IDTS: Month of NDATE = ', monew
1262 ! Check that the month of ODATE makes sense.
1264 IF ((moold.GT.12).or.(moold.LT.1)) THEN
1265 WRITE (iout,'(A,I2)') ' GETH_IDTS: Month of ODATE = ', moold
1269 ! Check that the day of NDATE makes sense.
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
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
1285 ! Check that the day of ODATE makes sense.
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
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
1301 ! Check that the hour of NDATE makes sense.
1303 IF ((hrnew.GT.23).or.(hrnew.LT.0)) THEN
1304 ! WRITE (iout,'(A,I2)') ' GETH_IDTS: Hour of NDATE = ', hrnew
1308 ! Check that the hour of ODATE makes sense.
1310 IF ((hrold.GT.23).or.(hrold.LT.0)) THEN
1311 ! WRITE (iout,'(A,I2)') ' GETH_IDTS: Hour of ODATE = ', hrold
1315 ! Check that the minute of NDATE makes sense.
1317 IF ((minew.GT.59).or.(minew.LT.0)) THEN
1318 WRITE (iout,'(A,I2)') ' GETH_IDTS: Minute of NDATE = ', minew
1322 ! Check that the minute of ODATE makes sense.
1324 IF ((miold.GT.59).or.(miold.LT.0)) THEN
1325 WRITE (iout,'(A,I2)') ' GETH_IDTS: Minute of ODATE = ', miold
1329 ! Check that the second of NDATE makes sense.
1331 IF ((scnew.GT.59).or.(scnew.LT.0)) THEN
1332 WRITE (iout,'(A,I2)') ' GETH_IDTS: SECOND of NDATE = ', scnew
1336 ! Check that the second of ODATE makes sense.
1338 IF ((scold.GT.59).or.(scold.LT.0)) THEN
1339 WRITE (iout,'(A,I2)') ' GETH_IDTS: Second of ODATE = ', scold
1343 IF (.not. npass) THEN
1344 IF (PRESENT (pass)) THEN
1347 WRITE (iout,'(A,A)') 'Screwy NDATE: ', lndate(1:nlen)
1348 IF (isign == -1) THEN
1359 IF (.not. opass) THEN
1360 IF (PRESENT (pass)) THEN
1363 WRITE (iout,'(A,A)') 'Screwy ODATE: ', odate(1:nlen)
1364 IF (isign == -1) THEN
1375 ! Date Checks are completed. Continue.
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
1382 DO i = yrold, yrnew - 1
1383 newdys = newdys + 365 + (nfeb(i)-28)
1386 IF (monew .GT. 1) THEN
1387 mday(2) = nfeb(yrnew)
1389 newdys = newdys + mday(i)
1394 newdys = newdys + dynew-1
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
1401 IF (moold .GT. 1) THEN
1402 mday(2) = nfeb(yrold)
1404 olddys = olddys + mday(i)
1409 olddys = olddys + dyold-1
1411 ! Determine the time difference in seconds
1413 idts = (newdys - olddys) * 86400
1414 idts = idts + (hrnew - hrold) * 3600
1415 idts = idts + (minew - miold) * 60
1416 idts = idts + (scnew - scold)
1418 IF (isign .eq. -1) THEN
1425 END SUBROUTINE geth_idts_2
1427 END MODULE module_date