WAVEWATCH III  beta 0.0.1
w3timemd.F90
Go to the documentation of this file.
1 #include "w3macros.h"
2 !/ ------------------------------------------------------------------- /
3 MODULE w3timemd
4  !/
5  !/ +-----------------------------------+
6  !/ | WAVEWATCH III NOAA/NCEP |
7  !/ | H. L. Tolman |
8  !/ | FORTRAN 90 |
9  !/ | Last update : 23-Feb-2024 |
10  !/ +-----------------------------------+
11  !/
12  !/ Copyright 2009 National Weather Service (NWS),
13  !/ National Oceanic and Atmospheric Administration. All rights
14  !/ reserved. WAVEWATCH III is a trademark of the NWS.
15  !/ No unauthorized use without permission.
16  !/
17  ! 1. Purpose :
18  !
19  ! Routines for management of date and time.
20  !
21  ! 2. Variables and types :
22  !
23  ! Name Type Scope Description
24  ! ----------------------------------------------------------------
25  ! PRFTB I.A. Private Base time for profiling.
26  ! FLPROF Log. Private Flag for profiling initialization.
27  ! ----------------------------------------------------------------
28  !
29  ! 3. Subroutines and functions :
30  !
31  ! Name Type Scope Description
32  ! ----------------------------------------------------------------
33  ! TICK21 Subr. Public Increment a date and time array with
34  ! a given number of seconds.
35  ! IYMD21 I.F. TICK21 Date increment function.
36  ! DSEC21 R.F. Public Calculate the difference in seconds
37  ! between two data/time arrays.
38  ! TDIFF R.F. Public Calculate the difference in seconds
39  ! between two date/time arrays that
40  ! were generated from DATE_AND_TIME
41  ! MYMD21 I.F. DSEC21 Julian date function.
42  ! STME21 Subr. Public Converts integer time to string.
43  ! JULDAY I.F. Public Julian date function
44  ! CALDAT Subr. Public Transform Julian day to date
45  ! PRINIT Subr. Public Initialize profiling.
46  ! PRTIME Subr. Public Get profiling time.
47  ! D2J Subr. Public Convert date array to julian date
48  ! J2D Subr. Public Convert julian date to date array
49  ! T2D Subr. Public Convert time array to date array
50  ! TSUB I.D. Public Substract two time arrays in days
51  ! TSUBSEC I.D. Public Substract two time arrays in seconds
52  ! U2D Subr. Public Convert time units attribute to date array
53  ! T2ISO Subr. Public Convert time array to ISO time string
54  ! ----------------------------------------------------------------
55  !
56  ! 4. Subroutines and functions used :
57  !
58  ! Name Type Module Description
59  ! ----------------------------------------------------------------
60  ! STRACE Subr. W3SERVMD Subroutine tracing.
61  ! ----------------------------------------------------------------
62  !
63  ! 5. Remarks :
64  !
65  ! 6. Switches :
66  !
67  ! 7. Source code :
68  !
69  !/ ------------------------------------------------------------------- /
70  !/
71 #ifdef W3_S
72  USE w3servmd, ONLY: strace
73 #endif
74  !
75  PUBLIC
76  !
77  INTEGER, PRIVATE :: PRFTB(8)
78  LOGICAL, PRIVATE :: FLPROF = .false.
79  CHARACTER, PUBLIC :: caltype*8
80  !
81 CONTAINS
82  !/ ------------------------------------------------------------------- /
83  SUBROUTINE tick21 ( TIME, DTIME )
84  !/
85  !/ +-----------------------------------+
86  !/ | WAVEWATCH III NOAA/NCEP |
87  !/ | H. L. Tolman |
88  !/ | FORTRAN 90 |
89  !/ | Last update : 29-Nov-1999 |
90  !/ +-----------------------------------+
91  !/ Based on TICK of the GLA GCM.
92  !/
93  !/ 23-Mar-1993 : Final FORTRAN 77 ( version 1.18 )
94  !/ 29-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
95  !/
96  ! 1. Purpose :
97  !
98  ! Updates time information, DTIME=0 converts to "legal" time.
99  ! Goes into the 21st century.
100  !
101  ! 3. Parameters :
102  !
103  ! Parameter list
104  ! ----------------------------------------------------------------
105  ! TIME I.A. I/O (1) Current date in YYYYMMDD format.
106  ! (2) Current time in HHMMSS format.
107  ! DTIME Real I Time step in seconds.
108  ! ----------------------------------------------------------------
109  !
110  ! 4. Subroutines used :
111  !
112  ! Name Type Module Description
113  ! ----------------------------------------------------------------
114  ! STRACE Subr. W3SERVMD Subroutine tracing.
115  ! IYMD21 Func. Internal Increment date in YYYYMMDD format.
116  ! ----------------------------------------------------------------
117  !
118  ! 5. Called by :
119  !
120  ! Any other routine.
121  !
122  ! 8. Structure :
123  !
124  ! See source code.
125  !
126  ! 9. Switches :
127  !
128  ! !/S Enable subroutine tracing using STRACE.
129  !
130  ! 10. Source code :
131  !
132  !/ ------------------------------------------------------------------- /
133  !/
134  IMPLICIT NONE
135  !/
136  !/ ------------------------------------------------------------------- /
137  !/ Parameter list
138  !/
139  INTEGER, INTENT(INOUT) :: TIME(2)
140  REAL, INTENT(IN) :: DTIME
141  !/
142  !/ ------------------------------------------------------------------- /
143  !/ Local parameters
144  !/
145  INTEGER :: NYMD, NHMS, NSEC
146 #ifdef W3_S
147  INTEGER, SAVE :: IENT = 0
148 #endif
149  !/
150  !/ ------------------------------------------------------------------- /
151  !/
152 #ifdef W3_S
153  CALL strace (ient, 'TICK21')
154 #endif
155  !
156  ! Zero increment: get "legal" date
157  !
158  nymd = time(1)
159  nhms = time(2)
160  IF (dtime.EQ.0.) THEN
161  nymd = iymd21(nymd,-1)
162  nymd = iymd21(nymd, 1)
163  END IF
164  !
165  ! Convert and increment time :
166  !
167  nsec = nhms/10000*3600 + mod(nhms,10000)/100* 60 + &
168  mod(nhms,100) + nint(dtime)
169  !
170  ! Check change of date :
171  !
172 100 CONTINUE
173  IF (nsec.GE.86400) THEN
174  nsec = nsec - 86400
175  nymd = iymd21(nymd,1)
176  GOTO 100
177  END IF
178  !
179 200 CONTINUE
180  IF (nsec.LT.00000) THEN
181  nsec = 86400 + nsec
182  nymd = iymd21(nymd,-1)
183  GOTO 200
184  END IF
185  !
186  nhms = nsec/3600*10000 + mod(nsec,3600)/60*100 + mod(nsec,60)
187  !
188  time(1) = nymd
189  time(2) = nhms
190  !
191  RETURN
192  !/
193  !/ Internal function IYMD21 ------------------------------------------ /
194  !/
195  CONTAINS
196  !/ ------------------------------------------------------------------- /
197  INTEGER FUNCTION iymd21 ( NYMD ,M )
198  !/
199  !/ +-----------------------------------+
200  !/ | WAVEWATCH III NOAA/NCEP |
201  !/ | H. L. Tolman |
202  !/ | FORTRAN 90 |
203  !/ | Last update : 18-Jun-2020 |
204  !/ +-----------------------------------+
205  !/ Based on INCYMD of the GLA GCM.
206  !/
207  !/ 18-Oct-1998 : Final FORTRAN 77 ( version 1.18 )
208  !/ 29-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
209  !/ 10-Jan-2017 : Add NOLEAP option, 365 day calendar ( version 6.00 )
210  !/ 18-Jun-2020 : Add 360-day calendar option ( version 7.08 )
211  !/
212  ! 1. Purpose :
213  !
214  ! Increment date in YYYYMMDD format by +/- 1 day.
215  !
216  ! 3. Parameters :
217  !
218  ! Parameter list
219  ! ----------------------------------------------------------------
220  ! NYMD Int. I Old date in YYMMDD format.
221  ! M Int. I +/- 1 (Day adjustment)
222  ! ----------------------------------------------------------------
223  !
224  ! 4. Subroutines used :
225  !
226  ! Name Type Module Description
227  ! ----------------------------------------------------------------
228  ! STRACE Subr. W3SERVMD Subroutine tracing.
229  ! ----------------------------------------------------------------
230  !
231  ! 5. Called by :
232  !
233  ! Any subroutine.
234  !
235  ! 8. Structure :
236  !
237  ! See source code.
238  !
239  ! 9. Switches :
240  !
241  ! !/S Enable subroutine tracing using STRACE.
242  !
243  ! 10. Source code :
244  !
245  !/ ------------------------------------------------------------------- /
246  !/
247  IMPLICIT NONE
248  !/
249  !/ ------------------------------------------------------------------- /
250  !/ Parameter list
251  !/
252  INTEGER, INTENT(IN) :: nymd, m
253  !/
254  !/ ------------------------------------------------------------------- /
255  !/ Local parameters
256  !/
257  INTEGER :: ny, nm, nd
258  INTEGER, SAVE :: ndpm(12)
259 #ifdef W3_S
260  INTEGER, SAVE :: ient = 0
261 #endif
262  LOGICAL :: leap
263  !/
264  !/ ------------------------------------------------------------------- /
265  !/
266 #ifdef W3_S
267  CALL strace (ient, 'IYMD21')
268 #endif
269  !
270  ! Declare the number of days in month depending on calendar
271  !
272  IF (trim(caltype) .EQ. '360_day' ) THEN
273  ndpm=(/ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 /)
274  ELSE
275  ndpm=(/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
276  END IF
277  !
278  ! "Unpack" and increment date :
279  !
280  ny = nymd / 10000
281  nm = mod(nymd,10000) / 100
282  nm = min( 12 , max(1,nm) )
283  nd = mod(nymd,100) + m
284  ! Add override for simulations with no leap years
285  IF (trim(caltype) .EQ. 'standard' ) THEN
286  leap = mod(ny,400).EQ.0 .OR. &
287  ( mod(ny,4).EQ.0 .AND. mod(ny,100).NE.0 )
288  ELSE
289  leap = .false.
290  END IF
291  !
292  ! M = -1, change month if necessary :
293  !
294  IF (nd.EQ.0) THEN
295  nm = nm - 1
296  IF (nm.EQ.0) THEN
297  nm = 12
298  ny = ny - 1
299  ENDIF
300  nd = ndpm(nm)
301  IF (nm.EQ.2 .AND. leap) nd = 29
302  END IF
303  !
304  ! M = 1, leap year
305  !
306  IF (nd.EQ.29 .AND. nm.EQ.2 .AND. leap) GO TO 20
307  !
308  ! next month
309  !
310  IF (nd.GT.ndpm(nm)) THEN
311  nd = 1
312  nm = nm + 1
313  IF (nm.GT.12) THEN
314  nm = 1
315  ny = ny + 1
316  ENDIF
317  END IF
318  !
319 20 CONTINUE
320  iymd21 = ny*10000 + nm*100 + nd
321  !
322  RETURN
323  !/
324  !/ End of IYMD21 ----------------------------------------------------- /
325  !/
326  END FUNCTION iymd21
327  !/
328  !/ End of TICK21 ----------------------------------------------------- /
329  !/
330  END SUBROUTINE tick21
331  !/ ------------------------------------------------------------------- /
332  REAL function dsec21 ( time1, time2 )
333  !/
334  !/ +-----------------------------------+
335  !/ | WAVEWATCH III NOAA/NCEP |
336  !/ | H. L. Tolman |
337  !/ | FORTRAN 90 |
338  !/ | Last update : 18-Jun-2020 |
339  !/ +-----------------------------------+
340  !/
341  !/ 23-Mar-1993 : Final FORTRAN 77 ( version 1.18 )
342  !/ 29-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
343  !/ 05-Jan-2001 : Y2K leap year error correction. ( version 2.05 )
344  !/ 18-Jun-2020 : Add 360-day calendar support ( version 7.08 )
345  !/
346  !/
347  ! 1. Purpose :
348  !
349  ! Calculate the time difference in seconds between two times in
350  ! YYMMD HHMMMSS formats.
351  !
352  ! 3. Parameters :
353  !
354  ! Parameter list
355  ! ----------------------------------------------------------------
356  ! TIMEn I.A. I Times, TIMEn(1) is date in YYYYMMDD format,
357  ! TIMEn(2) is time in HHMMSS format.
358  ! ----------------------------------------------------------------
359  !
360  ! 4. Subroutines used :
361  !
362  ! Name Type Module Description
363  ! ----------------------------------------------------------------
364  ! STRACE Subr. W3SERVMD Subroutine tracing.
365  ! MYMD21 Func. Internal Calculate Julian date.
366  ! ----------------------------------------------------------------
367  !
368  ! 5. Called by :
369  !
370  ! Any routine.
371  !
372  ! 7. Remarks :
373  !
374  ! 8. Structure :
375  !
376  ! See source code.
377  !
378  ! 9. Switches :
379  !
380  ! !/S Enable subroutine tracing using STRACE.
381  !
382  ! 10. Source code :
383  !
384  !/ ------------------------------------------------------------------- /
385  !/
386  IMPLICIT NONE
387  !/
388  !/ ------------------------------------------------------------------- /
389  !/ Parameter list
390  !/
391  INTEGER, INTENT(IN) :: time1(2), time2(2)
392  !/
393  !/ ------------------------------------------------------------------- /
394  !/ Local parameters
395  !/
396  INTEGER :: ny1, nd1, ny2, nd2, ns1, ns2, ns, &
397  nd, nst
398 #ifdef W3_S
399  INTEGER, SAVE :: ient = 0
400 #endif
401  !/
402  !/ ------------------------------------------------------------------- /
403  !/
404 #ifdef W3_S
405  CALL strace (ient, 'DSEC21')
406 #endif
407  !
408  ! Convert dates and times :
409  !
410  ny1 = time1(1) / 10000
411  nd1 = mymd21( time1(1) )
412  ns1 = time1(2)/10000*3600 + mod(time1(2),10000)/100*60 + &
413  mod(time1(2),100)
414  !
415  ny2 = time2(1) / 10000
416  nd2 = mymd21( time2(1) )
417  ns2 = time2(2)/10000*3600 + mod(time2(2),10000)/100*60 + &
418  mod(time2(2),100)
419  !
420  ! Number of days and seconds in difference :
421  !
422  nd = nd2 - nd1
423  !
424  IF ( ny1 .NE. ny2 ) THEN
425  nst = sign( 1 , ny2-ny1 )
426 100 CONTINUE
427  IF (ny1.EQ.ny2) GOTO 200
428  IF (nst.GT.0) THEN
429  ny2 = ny2 - 1
430  IF (trim(caltype) .EQ. '360_day' ) THEN
431  nd = nd + mymd21( ny2*10000 + 1230 )
432  ELSE
433  nd = nd + mymd21( ny2*10000 + 1231 )
434  END IF
435  ELSE
436  IF (trim(caltype) .EQ. '360_day' ) THEN
437  nd = nd - mymd21( ny2*10000 + 1230 )
438  ELSE
439  nd = nd - mymd21( ny2*10000 + 1231 )
440  END IF
441  ny2 = ny2 + 1
442  ENDIF
443  GOTO 100
444 200 CONTINUE
445  END IF
446  !
447  ns = ns2 - ns1
448  !
449  ! Output of time difference :
450  !
451  dsec21 = real(ns) + 86400.*real(nd)
452  !
453  RETURN
454  !/
455  !/ Internal function MYMD21 ------------------------------------------ /
456  !/
457  CONTAINS
458  !/ ------------------------------------------------------------------- /
459  INTEGER FUNCTION mymd21 ( NYMD )
460  !/
461  !/ +-----------------------------------+
462  !/ | WAVEWATCH III NOAA/NCEP |
463  !/ | H. L. Tolman |
464  !/ | FORTRAN 90 |
465  !/ | Last update : 18-Jun-2020 |
466  !/ +-----------------------------------+
467  !/ Based on MODYMD of the GLA GCM.
468  !/
469  !/ 19-Oct-1998 : Final FORTRAN 77 ( version 1.18 )
470  !/ 29-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
471  !/ 10-Jan-2017 : Add NOLEAP option, 365 day calendar ( version 6.01 )
472  !/ 18-Jun-2020 : Add 360-day calendar support ( version 7.08 )
473  !/
474  ! 1. Purpose :
475  !
476  ! Convert date in YYMMDD format to julian date.
477  !
478  ! 3. Parameters :
479  !
480  ! Parameter list
481  ! ----------------------------------------------------------------
482  ! NYMD Int. I Date in YYMMDD format.
483  ! ----------------------------------------------------------------
484  !
485  ! 4. Subroutines used :
486  !
487  ! Name Type Module Description
488  ! ----------------------------------------------------------------
489  ! STRACE Subr. W3SERVMD Subroutine tracing.
490  ! ----------------------------------------------------------------
491  !
492  ! 5. Called by :
493  !
494  ! Any subroutine.
495  !
496  ! 8. Structure :
497  !
498  ! See source code.
499  !
500  ! 9. Switches :
501  !
502  ! !/S Enable subroutine tracing using STRACE.
503  !
504  ! 10. Source code :
505  !
506  !/ ------------------------------------------------------------------- /
507  !/
508  IMPLICIT NONE
509  !/
510  !/ ------------------------------------------------------------------- /
511  !/ Parameter list
512  !/
513  INTEGER, INTENT(IN) :: nymd
514  !/
515  !/ ------------------------------------------------------------------- /
516  !/ Local parameters
517  !/
518  INTEGER :: ny, nm, nd
519  INTEGER, SAVE :: ndpm(12)
520 #ifdef W3_S
521  INTEGER, SAVE :: ient = 0
522 #endif
523  LOGICAL :: leap
524  !/
525  !/ ------------------------------------------------------------------- /
526  !/
527 #ifdef W3_S
528  CALL strace (ient, 'MYMD21')
529 #endif
530  !
531  ! Declare the number of days in month depending on calendar
532  !
533  IF (trim(caltype) .EQ. '360_day' ) THEN
534  ndpm=(/ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30 /)
535  ELSE
536  ndpm=(/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
537  END IF
538  !
539  ! "Unpack" and increment date :
540  !
541  ny = nymd / 10000
542  nm = mod(nymd,10000) / 100
543  nd = mod(nymd,100)
544  !Allow override for NoLeap simulations
545  IF (trim(caltype) .EQ. 'standard' ) THEN
546  leap = mod(ny,400).EQ.0 .OR. &
547  ( mod(ny,4).EQ.0 .AND. mod(ny,100).NE.0 )
548  ELSE
549  leap=.false.
550  ENDIF
551  !
552  ! Loop over months :
553  !
554  IF (nm.GT.2 .AND. leap) nd = nd + 1
555  !
556 40 CONTINUE
557  IF (nm.LE.1) GO TO 60
558  nm = nm - 1
559  nd = nd + ndpm(nm)
560  GO TO 40
561  !
562 60 CONTINUE
563  mymd21 = nd
564  !
565  RETURN
566  !/
567  !/ End of MYMD21 ----------------------------------------------------- /
568  !/
569  END FUNCTION mymd21
570  !/
571  !/ End of DSEC21 ----------------------------------------------------- /
572  !/
573  END FUNCTION dsec21
574  !/ ------------------------------------------------------------------- /
575  REAL function tdiff ( t1, t2 )
576  !/
577  !/ +-----------------------------------+
578  !/ | WAVEWATCH III NOAA/NCEP |
579  !/ | Arun Chawla |
580  !/ | Mark Szyszka |
581  !/ | FORTRAN 90 |
582  !/ | Last update : 02-Feb-2014 |
583  !/ +-----------------------------------+
584  !/
585  !/ 02-Feb-2014 : Original code ( version 4.18 )
586  !/
587  !/
588  ! 1. Purpose :
589  !
590  ! Calculate the time difference in seconds between two time arrays
591  ! that have been generated from the F90 internal function
592  !
593  ! 3. Parameters :
594  !
595  ! Parameter list
596  ! ----------------------------------------------------------------
597  ! Tn I.A. I This is an integer array returned from the
598  ! internal subroutine DATE_AND_TIME. The type
599  ! is integer(8). Individual values are
600  ! Tn(1) the year
601  ! Tn(2) the month
602  ! Tn(3) day of the month
603  ! Tn(4) time difference with UTC in minutes
604  ! Tn(5) hour of the day
605  ! Tn(6) minutes of the hour
606  ! Tn(7) seconds of the minute
607  ! Tn(8) milli seconds of the second
608  ! ----------------------------------------------------------------
609  !
610  ! 4. Subroutines used :
611  !
612  ! Name Type Module Description
613  ! ----------------------------------------------------------------
614  ! STRACE Subr. W3SERVMD Subroutine tracing.
615  ! ----------------------------------------------------------------
616  !
617  ! 5. Called by :
618  !
619  ! Any routine.
620  !
621  ! 7. Remarks :
622  !
623  ! This code has been provided by Mark Szyszka of RPSGROUP
624  !
625  ! 8. Structure :
626  !
627  ! See source code.
628  !
629  ! 9. Switches :
630  !
631  ! !/S Enable subroutine tracing using STRACE.
632  !
633  ! 10. Source code :
634  !
635  !/ ------------------------------------------------------------------- /
636  !/
637  IMPLICIT NONE
638  !/
639  !/ ------------------------------------------------------------------- /
640  !/ Parameter list
641  !/
642  INTEGER, INTENT(IN) :: t1(8), t2(8)
643  !/
644  !/ ------------------------------------------------------------------- /
645  !/ Local parameters
646  !/
647  INTEGER :: a1, b1, c1, d1, a2, b2, c2, d2
648  REAL :: e1, e2
649 #ifdef W3_S
650  INTEGER, SAVE :: ient = 0
651 #endif
652  !/
653  !/ ------------------------------------------------------------------- /
654  !/
655 #ifdef W3_S
656  CALL strace (ient, 'TDIFF')
657 #endif
658  !
659  ! Convert dates and times :
660  !
661  a1 = (14-t1(2))/12
662  b1 = t1(1) + 4800 - a1
663  c1 = t1(2) + 12*a1 - 3
664  d1 = t1(3) + (153*c1 + 2)/5 + 365*b1 + b1/4 -b1/100 + b1/400
665  e1 = 3600.0*t1(5) + 60.0*(t1(6)-t1(4)) + t1(7) + t1(8)/1000.0
666  !
667  a2 = (14-t2(2))/12
668  b2 = t2(1) + 4800 - a2
669  c2 = t2(2) + 12*a2 - 3
670  d2 = t2(3) + (153*c2 + 2)/5 + 365*b2 + b2/4 -b2/100 + b2/400
671  e2 = 3600.0*t2(5) + 60.0*(t2(6)-t2(4)) + t2(7) + t2(8)/1000.0
672  !
673  tdiff = 86400.0*(d2-d1) + e2-e1
674  !
675  RETURN
676  !/
677  !/ End of TDIFF ------------------------------------------------------ /
678  !/
679  END FUNCTION tdiff
680  !/ ------------------------------------------------------------------- /
681  SUBROUTINE stme21 ( TIME , DTME21 )
682  !/
683  !/ +-----------------------------------+
684  !/ | WAVEWATCH III NOAA/NCEP |
685  !/ | H. L. Tolman |
686  !/ | FORTRAN 90 |
687  !/ | Last update : 23-Nov-1999 |
688  !/ +-----------------------------------+
689  !/
690  !/ 21-Jun-1993 : Final FORTRAN 77 ( version 1.18 )
691  !/ 23-Nov-1999 : Upgrade to FORTRAN 90 ( version 2.00 )
692  !/
693  ! 1. Purpose :
694  !
695  ! Converts time to more readable string.
696  !
697  ! 3. Parameters :
698  !
699  ! Parameter list
700  ! ----------------------------------------------------------------
701  ! TIME I.A. I Time in YYYYMMDD HHMMSS format.
702  ! TIME(1) < 0 indicates that time is not set.
703  ! ----------------------------------------------------------------
704  !
705  ! 4. Subroutines used :
706  !
707  ! None.
708  !
709  ! 5. Called by :
710  !
711  ! Any subroutine/program.
712  !
713  ! 10. Source code :
714  !
715  !/ ------------------------------------------------------------------- /
716  !/
717  IMPLICIT NONE
718  !/
719  !/ ------------------------------------------------------------------- /
720  !/ Parameter list
721  !/
722  INTEGER, INTENT(IN) :: TIME(2)
723  CHARACTER, INTENT(OUT) :: DTME21*23
724  !/
725  !/ ------------------------------------------------------------------- /
726  !/ Local parameters
727  !/
728  INTEGER :: IY, IMO, ID, IH, IMI, IS
729  !/
730  !/ ------------------------------------------------------------------- /
731  !/
732  IF ( time(1) .LT. 0 ) THEN
733  dtme21 = ' date and time not set.'
734  ELSE
735  iy = time(1) / 10000
736  imo = mod(time(1),10000) / 100
737  id = mod(time(1),100)
738  ih = time(2) / 10000
739  imi = mod(time(2),10000) / 100
740  is = mod(time(2),100)
741  WRITE (dtme21,900) iy, imo, id, ih, imi, is
742  ENDIF
743  !
744  RETURN
745  !
746  ! Formats
747  !
748 900 FORMAT (i4.4,'/',i2.2,'/',i2.2,' ',i2.2,':',i2.2,':',i2.2,' UTC')
749  !/
750  !/ End of STME21 ----------------------------------------------------- /
751  !/
752  END SUBROUTINE stme21
753 
754  !/ ------------------------------------------------------------------- /
755  INTEGER FUNCTION julday(id,mm,iyyy)
756  !/
757  !/ +-----------------------------------+
758  !/ | WAVEWATCH III NOAA/NCEP |
759  !/ | F. Ardhuin |
760  !/ | FORTRAN 90 |
761  !/ | Last update : 23-Sep-2012 |
762  !/ +-----------------------------------+
763  !
764  ! 10. Source code :
765  !
766  !/ ------------------------------------------------------------------- /
767  !/
768  IMPLICIT NONE
769  !/
770  !/ ------------------------------------------------------------------- /
771  INTEGER(KIND=4), INTENT(in) :: id,mm,iyyy
772  !/
773  !/ ------------------------------------------------------------------- /
774  !/ Local parameters
775  !/
776  INTEGER(KIND=4), PARAMETER :: igreg=15+31*(10+12*1582)
777  INTEGER(KIND=4) ja,jm,jy
778  jy=iyyy
779  IF (jy.EQ.0) WRITE(6,*) 'There is no zero year !!'
780  IF (jy.LT.0) jy=jy+1
781  IF (mm.GT.2) THEN
782  jm=mm+1
783  ELSE
784  jy=jy-1
785  jm=mm+13
786  ENDIF
787  julday=int(365.25*jy)+int(30.6001*jm)+id+1720995
788  IF (id+31*(mm+12*iyyy).GE.igreg) THEN
789  ja=int(0.01*jy)
790  julday=julday+2-ja+int(0.25*ja)
791  END IF
792  RETURN
793  !/
794  !/ End of JULDAY ----------------------------------------------------- /
795  !/
796  END FUNCTION julday
797 
798  !/ ------------------------------------------------------------------- /
799  SUBROUTINE caldat(julian,id,mm,iyyy)
800  !/
801  !/ +-----------------------------------+
802  !/ | WAVEWATCH III NOAA/NCEP |
803  !/ | F. Ardhuin |
804  !/ | FORTRAN 90 |
805  !/ | Last update : 23-Sep-2012 |
806  !/ +-----------------------------------+
807  !
808  ! 10. Source code :
809  !
810  !/ ------------------------------------------------------------------- /
811  !/
812  IMPLICIT NONE
813  !/
814  ! See numerical recipes 2nd ed. The order of month and day have been swapped!
815  !
816  !/
817  INTEGER(KIND=4), INTENT(in) :: julian
818  INTEGER(KIND=4), INTENT(out) :: id,mm,iyyy
819  INTEGER(KIND=4), PARAMETER :: IGREG=2299161
820  INTEGER(KIND=4) ja,jalpha,jb,jc,jd,je
821  if (julian.GE.igreg) THEN
822  jalpha=int(((julian-1867216)-0.25)/36524.25)
823  ja=julian+1+jalpha-int(0.25*jalpha)
824  ELSE
825  ja=julian
826  END IF
827  jb=ja+1524
828  jc=int(6680.+((jb-2439870)-122.1)/365.25)
829  jd=365*jc+int(0.25*jc)
830  je=int((jb-jd)/30.6001)
831  id=jb-jd-int(30.6001*je)
832  mm=je-1
833  IF (mm.GT.12) mm=mm-12
834  iyyy=jc-4715
835  IF (mm.GT.2) iyyy=iyyy-1
836  IF (iyyy.LE.0) iyyy=iyyy-1
837  RETURN
838  !/
839  !/ End of CALDAT ----------------------------------------------------- /
840  !/
841  END SUBROUTINE caldat
842  !/ ------------------------------------------------------------------- /
843  REAL(KIND=8) function time2hours(time)
844  !/
845  !/ +-----------------------------------+
846  !/ | WAVEWATCH III NOAA/NCEP |
847  !/ | F. Ardhuin |
848  !/ | FORTRAN 90 |
849  !/ | Last update : 26-Sep-2012 |
850  !/ +-----------------------------------+
851  !
852  ! 1. Purpose :
853  !
854  ! Gives date as real number
855  !
856  ! 2. Method :
857  !
858  ! 3. Parameters :
859  !
860  ! Parameter list
861  ! ----------------------------------------------------------------
862  ! TIME I.A. I/O (1) Current date in YYYYMMDD format.
863  ! (2) Current time in HHMMSS format.
864  ! DTIME Real I Time step in seconds.
865  ! ----------------------------------------------------------------
866  !
867  ! 4. Subroutines used :
868  !
869  ! Name Type Module Description
870  ! ----------------------------------------------------------------
871  ! STRACE Subr. W3SERVMD Subroutine tracing.
872  ! IYMD21 Func. Internal Increment date in YYYYMMDD format.
873  ! ----------------------------------------------------------------
874  !
875  ! 5. Called by :
876  !
877  ! Any other routine.
878  !
879  ! 8. Structure :
880  !
881  ! See source code.
882  !
883  ! 9. Switches :
884  !
885  ! !/S Enable subroutine tracing using STRACE.
886  !
887  ! 10. Source code :
888  !
889  !/ ------------------------------------------------------------------- /
890  !/
891  IMPLICIT NONE
892  !/
893  !/ ------------------------------------------------------------------- /
894  !/ Parameter list
895  !/
896  INTEGER, INTENT(INOUT) :: time(2)
897  !/
898  !/ ------------------------------------------------------------------- /
899  !/ Local parameters
900  !/
901  INTEGER :: iy,imo,id,ih,imi,is
902  INTEGER(KIND=4) :: jday
903 #ifdef W3_S
904  INTEGER, SAVE :: ient = 0
905 #endif
906  !/
907  !/ ------------------------------------------------------------------- /
908  !/
909 #ifdef W3_S
910  CALL strace (ient, 'TICK21')
911 #endif
912  !
913  ! Zero increment: get "legal" date
914  !
915  iy = time(1) / 10000
916  imo = mod(time(1),10000) / 100
917  id = mod(time(1),100)
918  ih = time(2) / 10000
919  imi = mod(time(2),10000) / 100
920  is = mod(time(2),100)
921  jday = julday(id,imo,iy)
922  time2hours = 24.d0*dfloat(jday)+dfloat(ih)+dfloat(is+imi*60)/3600.d0
923  RETURN
924  !/
925  !/ End of TIME2HOURS-------------------------------------------------- /
926  !/
927  END FUNCTION time2hours
928  !/ ------------------------------------------------------------------- /
929  SUBROUTINE prinit
930  !/
931  !/ +-----------------------------------+
932  !/ | WAVEWATCH III NOAA/NCEP |
933  !/ | H. L. Tolman |
934  !/ | FORTRAN 90 |
935  !/ | Last update : 06-May-2005 !
936  !/ +-----------------------------------+
937  !/
938  !/ 06-May-2005 : Origination. ( version 3.07 )
939  !/
940  ! 1. Purpose :
941  !
942  ! Initialize profiling routine PRTIME.
943  !
944  ! 2. Method :
945  !
946  ! FORTRAN 90 SYSTEM_CLOCK intrinsic routine.
947  !
948  ! 3. Parameters :
949  !
950  ! Parameter list
951  ! ----------------------------------------------------------------
952  ! ----------------------------------------------------------------
953  !
954  ! 4. Subroutines used :
955  !
956  ! Name Type Module Description
957  ! ----------------------------------------------------------------
958  ! SYSTEM_CLOCK
959  ! Sur. n/a Get system time
960  ! ----------------------------------------------------------------
961  !
962  ! 5. Called by :
963  !
964  ! 6. Error messages :
965  !
966  ! 7. Remarks :
967  !
968  ! 8. Structure :
969  !
970  ! 9. Switches :
971  !
972  ! 10. Source code :
973  !
974  !/ ------------------------------------------------------------------- /
975  IMPLICIT NONE
976  !/
977  ! -------------------------------------------------------------------- /
978  !
979  CALL date_and_time ( values=prftb )
980  !
981  flprof = .true.
982  !
983  RETURN
984  !/
985  !/ End of PRINIT ----------------------------------------------------- /
986  !/
987  END SUBROUTINE prinit
988  !/ ------------------------------------------------------------------- /
989  SUBROUTINE prtime ( PTIME )
990  !/
991  !/ +-----------------------------------+
992  !/ | WAVEWATCH III NOAA/NCEP |
993  !/ | H. L. Tolman |
994  !/ | FORTRAN 90 |
995  !/ | Last update : 06-May-2005 !
996  !/ +-----------------------------------+
997  !/
998  !/ 06-May-2005 : Origination. ( version 3.07 )
999  !/
1000  ! 1. Purpose :
1001  !
1002  ! Get wallclock time for profiling purposes.
1003  !
1004  ! 2. Method :
1005  !
1006  ! FORTRAN 90 SYSTEM_CLOCK intrinsic routine.
1007  !
1008  ! 3. Parameters :
1009  !
1010  ! Parameter list
1011  ! ----------------------------------------------------------------
1012  ! PTIME Real O Time retrieced from system.
1013  ! ----------------------------------------------------------------
1014  !
1015  ! 4. Subroutines used :
1016  !
1017  ! Name Type Module Description
1018  ! ----------------------------------------------------------------
1019  ! SYSTEM_CLOCK
1020  ! Sur. n/a Get system time
1021  ! ----------------------------------------------------------------
1022  !
1023  ! 5. Called by :
1024  !
1025  ! Any, after PRINIT has been called.
1026  !
1027  ! 6. Error messages :
1028  !
1029  ! - If no initialization, returned time equals -1.
1030  ! - If no system clock, returned time equals -1.
1031  !
1032  ! 7. Remarks :
1033  !
1034  ! 8. Structure :
1035  !
1036  ! 9. Switches :
1037  !
1038  ! 10. Source code :
1039  !
1040  !/ ------------------------------------------------------------------- /
1041  !/
1042  IMPLICIT NONE
1043  !/
1044  !/ ------------------------------------------------------------------- /
1045  !/ Parameter list
1046  !/
1047  REAL, INTENT(OUT) :: PTIME
1048  !/
1049  !/ ------------------------------------------------------------------- /
1050  !/ Local parameters
1051  !/
1052  INTEGER :: PRFTA(8)
1053  !
1054  ! -------------------------------------------------------------------- /
1055  !
1056  ptime = -1.
1057  !
1058  IF ( .NOT. flprof ) RETURN
1059  !
1060  CALL date_and_time ( values=prfta )
1061  ptime = tdiff( prftb,prfta )
1062  !
1063  RETURN
1064  !/
1065  !/ End of PRTIME ----------------------------------------------------- /
1066  !/
1067  END SUBROUTINE prtime
1068 
1069  !/ ------------------------------------------------------------------- /
1070 
1071  SUBROUTINE t2d(TIME,DAT,IERR)
1072  !/
1073  !/ +-----------------------------------+
1074  !/ | WAVEWATCH III NOAA/NCEP |
1075  !/ | M. Accensi |
1076  !/ | FORTRAN 90 |
1077  !/ | Last update : 04-Jan-2018 |
1078  !/ +-----------------------------------+
1079  !/
1080  !/ 04-Jan-2018 : Origination ( version 6.04 )
1081  !/
1082  ! 1. Purpose :
1083  !
1084  ! Converts time array from TIME(2) to DAT(8)
1085  !
1086  ! 3. Parameters :
1087  !
1088  ! Parameter list
1089  ! ----------------------------------------------------------------
1090  ! TIME I.A. I Time array like 'YYYYMMDD HHMMSS'
1091  ! DAT I.A. O Time array like returned by DATE_AND_TIME(3f)
1092  ! IERR Integer O Error code returned
1093  ! ----------------------------------------------------------------
1094  !
1095  ! 4. Subroutines used :
1096  !
1097  ! Name Type Module Description
1098  ! ----------------------------------------------------------------
1099  ! STRACE Subr. W3SERVMD Subroutine tracing.
1100  ! ----------------------------------------------------------------
1101  !
1102  ! 5. Called by :
1103  !
1104  ! Any subroutine/program.
1105  !
1106  ! 10. Source code :
1107  !
1108  !/ ------------------------------------------------------------------- /
1109  !/
1110  IMPLICIT NONE
1111  !/
1112  !/ ------------------------------------------------------------------- /
1113  !/ Parameter list
1114  !/
1115  INTEGER,INTENT(IN) :: TIME(2) ! array like 'YYYYMMDD HHMMSS'
1116  INTEGER,INTENT(OUT) :: DAT(8) ! array like returned by DATE_AND_TIME(3f)
1117  INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution
1118  ! Otherwise return 1
1119  !/
1120  !/ ------------------------------------------------------------------- /
1121  !/ Local parameters
1122  !/
1123 #ifdef W3_S
1124  INTEGER, SAVE :: IENT = 0
1125 #endif
1126  !/
1127  !/ ------------------------------------------------------------------- /
1128  !/
1129 #ifdef W3_S
1130  CALL strace (ient, 'T2D')
1131 #endif
1132  !
1133  dat(1)=time(1)/10000
1134  dat(2)=(time(1)-dat(1)*10000)/100
1135  dat(3)=time(1)-dat(1)*10000-100*dat(2)
1136  dat(4)=0
1137  dat(5)=time(2)/10000
1138  dat(6)=(time(2)-dat(5)*10000)/100
1139  dat(7)=time(2)-dat(5)*10000-100*dat(6)
1140  dat(8)=0
1141  ierr=0
1142  !
1143  RETURN
1144  !/
1145  !/ End of T2D ----------------------------------------------------- /
1146  !/
1147  END SUBROUTINE t2d
1148 
1149  !/ ------------------------------------------------------------------- /
1150 
1151 
1152  SUBROUTINE d2t(DAT,TIME,IERR)
1153  !/
1154  !/ +-----------------------------------+
1155  !/ | WAVEWATCH III NOAA/NCEP |
1156  !/ | M. Accensi |
1157  !/ | FORTRAN 90 |
1158  !/ | Last update : 04-Jan-2018 |
1159  !/ +-----------------------------------+
1160  !/
1161  !/ 04-Jan-2018 : Origination ( version 6.04 )
1162  !/
1163  ! 1. Purpose :
1164  !
1165  ! Converts time array from DAT(8) to TIME(2)
1166  !
1167  ! 3. Parameters :
1168  !
1169  ! Parameter list
1170  ! ----------------------------------------------------------------
1171  ! DAT I.A. I Time array like returned by DATE_AND_TIME(3f)
1172  ! TIME I.A. O Time array like 'YYYYMMDD HHMMSS'
1173  ! IERR Integer O Error code returned
1174  ! ----------------------------------------------------------------
1175  !
1176  ! 4. Subroutines used :
1177  !
1178  ! Name Type Module Description
1179  ! ----------------------------------------------------------------
1180  ! STRACE Subr. W3SERVMD Subroutine tracing.
1181  ! ----------------------------------------------------------------
1182  !
1183  ! 5. Called by :
1184  !
1185  ! Any subroutine/program.
1186  !
1187  ! 10. Source code :
1188  !
1189  !/ ------------------------------------------------------------------- /
1190  !/
1191  IMPLICIT NONE
1192  !/
1193  !/ ------------------------------------------------------------------- /
1194  !/ Parameter list
1195  !/
1196  INTEGER,INTENT(IN) :: DAT(8) ! array like returned by DATE_AND_TIME(3f)
1197  INTEGER,INTENT(OUT) :: TIME(2) ! array like 'YYYYMMDD HHMMSS'
1198  INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution
1199  ! Otherwise return 1
1200  !/
1201  !/ ------------------------------------------------------------------- /
1202  !/ Local parameters
1203  !/
1204 #ifdef W3_S
1205  INTEGER, SAVE :: IENT = 0
1206 #endif
1207  !/
1208  !/ ------------------------------------------------------------------- /
1209  !/
1210 #ifdef W3_S
1211  CALL strace (ient, 'D2T')
1212 #endif
1213  !
1214  time(1)=dat(1)*10000+dat(2)*100+dat(3)
1215  time(2)=dat(5)*10000+dat(6)*100+dat(7)
1216  ierr=0
1217  !
1218  RETURN
1219  !/
1220  !/ End of D2T ----------------------------------------------------- /
1221  !/
1222  END SUBROUTINE d2t
1223 
1224  !/ ------------------------------------------------------------------- /
1225 
1226  SUBROUTINE d2j(DAT,JULIAN,IERR)
1227  !/
1228  !/ +-----------------------------------+
1229  !/ | WAVEWATCH III NOAA/NCEP |
1230  !/ | M. Accensi |
1231  !/ | FORTRAN 90 |
1232  !/ | Last update : 04-Jan-2018 |
1233  !/ +-----------------------------------+
1234  !/
1235  !/ 04-Jan-2018 : Origination from m_time library ( version 6.04 )
1236  !/ 23-Feb-2024 : Updated to handle 360_day calendar ( version 7.14 )
1237  !/
1238  ! 1. Purpose :
1239  !
1240  ! Converts proleptic Gregorian date array to Julian Day
1241  !
1242  !
1243  ! * UDUNITS standard : mixed Gregorian/Julian calendar system.
1244  ! Dates prior to 1582-10-15 are assumed to use
1245  ! the Julian calendar, which was introduced by Julius Caesar
1246  ! in 46 BCE and is based on a year that is exactly 365.25 days
1247  ! long. Dates on and after 1582-10-15 are assumed to use the
1248  ! Gregorian calendar, which was introduced on that date and is
1249  ! based on a year that is exactly 365.2425 days long. (A year
1250  ! is actually approximately 365.242198781 days long.)
1251  !
1252  ! * There is no year zero
1253  ! * Julian Day must be non-negative
1254  ! * Julian Day starts at noon; while Civil Calendar date starts at midnight
1255  ! * If CALTYPE is "360_day" a simpler calculation is used (30 days in every
1256  ! month) with a reference date of 1800-01-01.
1257  !
1258  ! 3. Parameters :
1259  !
1260  ! Parameter list
1261  ! ----------------------------------------------------------------
1262  ! DAT I.A. I Time array like returned by DATE_AND_TIME(3f)
1263  ! JULIAN Double O Julian day
1264  ! IERR Integer O Error code returned
1265  ! ----------------------------------------------------------------
1266  !
1267  ! 4. Subroutines used :
1268  !
1269  ! Name Type Module Description
1270  ! ----------------------------------------------------------------
1271  ! STRACE Subr. W3SERVMD Subroutine tracing.
1272  ! ----------------------------------------------------------------
1273  !
1274  ! 5. Called by :
1275  !
1276  ! Any subroutine/program.
1277  !
1278  ! 10. Source code :
1279  !
1280  !/ ------------------------------------------------------------------- /
1281  !/
1282  IMPLICIT NONE
1283  !/
1284  !/ ------------------------------------------------------------------- /
1285  !/ Parameter list
1286  !/
1287  INTEGER,INTENT(IN) :: DAT(8) ! array like returned by DATE_AND_TIME(3f)
1288  DOUBLE PRECISION,INTENT(OUT) :: JULIAN ! Julian Day (non-negative, but may be non-integer)
1289  INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution
1290  ! -1=invalid year,-2=invalid month,-3=invalid day,
1291  ! -4=invalid date (29th Feb, non leap-year)
1292  !/
1293  !/ ------------------------------------------------------------------- /
1294  !/ Local parameters
1295  !/
1296  INTEGER :: YEAR, MONTH, DAY, UTC, HOUR, MINUTE
1297  REAL :: SECOND
1298  INTEGER :: A, Y, M, JDN
1299 #ifdef W3_S
1300  INTEGER, SAVE :: IENT = 0
1301 #endif
1302  !/
1303  !/ ------------------------------------------------------------------- /
1304  !/
1305 #ifdef W3_S
1306  CALL strace (ient, 'D2J')
1307 #endif
1308  !
1309  year = dat(1) ! Year
1310  month = dat(2) ! Month
1311  day = dat(3) ! Day
1312  utc = dat(4)*60 ! Delta from UTC, convert from minutes to seconds
1313  hour = dat(5) ! Hour
1314  minute = dat(6) ! Minute
1315  second = dat(7)-utc+dat(8)/1000.d0 ! Second ! correction for time zone and milliseconds
1316 
1317  julian = -huge(99999) ! this is the date if an error occurs and IERR is < 0
1318 
1319  ! Special case for 360 day climate calendar; return a pseudo-Julian day
1320  ! Assumes a reference date of 1800-01-01 00:00:00
1321  IF( caltype .EQ. "360_day" ) THEN
1322  julian = (year - 1800) * 360.0 + & ! Years since 1800
1323  (month - 1) * 30.0 + &
1324  (day - 1) + &
1325  hour / 24.0_8 + &
1326  minute / 1440.0_8 + &
1327  second / 86400.0_8
1328 
1329  ierr = 0
1330  RETURN
1331  ENDIF
1332 
1333  ! Standard/Gregorian calendar - return standard Julian day calculation:
1334  IF(year==0 .or. year .lt. -4713) THEN
1335  ierr=-1
1336  RETURN
1337  END IF
1338 
1339  ! You must compute first the number of years (Y) and months (M) since March 1st -4800 (March 1, 4801 BC)
1340  a=(14-month)/12 ! A will be 1 for January or Febuary, and 0 for other months, with integer truncation
1341  y=year+4800-a
1342  m=month+12*a-3 ! M will be 0 for March and 11 for Febuary
1343 
1344  ! All years in the BC era must be converted to astronomical years, so that 1BC is year 0, 2 BC is year "-1", etc.
1345  ! Convert to a negative number, then increment towards zero
1346  ! Starting from a Gregorian calendar date
1347  jdn=day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 - 32045 ! with integer truncation
1348 
1349  ! Finding the Julian date given the JDN (Julian day number) and time of day
1350  julian=dble(jdn) + dble(hour-12)/24.0d0 + dble(minute)/1440.0d0 + dble(second)/86400.0d0
1351 
1352  ! Check if Julian Day is non-negative
1353  IF(julian.lt.0.d0) THEN
1354  ierr=1
1355  ELSE
1356  ierr=0
1357  END IF
1358  !
1359  RETURN
1360  !/
1361  !/ End of D2J ----------------------------------------------------- /
1362  !/
1363  END SUBROUTINE d2j
1364 
1365  !/ ------------------------------------------------------------------- /
1366 
1367  SUBROUTINE j2d(JULIAN,DAT,IERR)
1368  !/
1369  !/ +-----------------------------------+
1370  !/ | WAVEWATCH III NOAA/NCEP |
1371  !/ | M. Accensi |
1372  !/ | FORTRAN 90 |
1373  !/ | Last update : 04-Jan-2018 |
1374  !/ +-----------------------------------+
1375  !/
1376  !/ 04-Jan-2018 : Origination from m_time library ( version 6.04 )
1377  !/ 23-Feb-2024 : Upated to handle 360_day calendar ( version 7.14 )
1378  !/
1379  ! 1. Purpose :
1380  !
1381  ! Converts Julian Day to date array
1382  !
1383  ! * There is no year zero
1384  ! * Julian Day must be non-negative
1385  ! * Julian Day starts at noon; while Civil Calendar date starts at midnight
1386  ! * If CALTYPE is "360_day" a simpler calculation is used (30 days in every
1387  ! month) with a reference date of 1800-01-01.
1388  !
1389  ! 3. Parameters :
1390  !
1391  ! Parameter list
1392  ! ----------------------------------------------------------------
1393  ! JULIAN Double I Julian day
1394  ! DAT I.A. O Time array like returned by DATE_AND_TIME(3f)
1395  ! IERR Integer O Error code returned
1396  ! ----------------------------------------------------------------
1397  !
1398  ! 4. Subroutines used :
1399  !
1400  ! Name Type Module Description
1401  ! ----------------------------------------------------------------
1402  ! STRACE Subr. W3SERVMD Subroutine tracing.
1403  ! ----------------------------------------------------------------
1404  !
1405  ! 5. Called by :
1406  !
1407  ! Any subroutine/program.
1408  !
1409  ! 10. Source code :
1410  !
1411  !/ ------------------------------------------------------------------- /
1412  !/
1413  IMPLICIT NONE
1414  !/
1415  !/ ------------------------------------------------------------------- /
1416  !/ Parameter list
1417  !/
1418  DOUBLE PRECISION,INTENT(IN) :: JULIAN ! Julian Day (non-negative, but may be non-integer)
1419  INTEGER,INTENT(OUT) :: DAT(8) ! array like returned by DATE_AND_TIME(3f)
1420  INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution
1421  ! ! otherwise return 1
1422  !/
1423  !/ ------------------------------------------------------------------- /
1424  !/ Local parameters
1425  !/
1426  REAL :: SECDAY=86400.0d0
1427  INTEGER :: TIMEZONE(8), TZ
1428 
1429  REAL :: SECOND
1430  INTEGER :: YEAR, MONTH, DAY, HOUR, MINUTE
1431  INTEGER :: JALPHA,JA,JB,JC,JD,JE,IJUL
1432 #ifdef W3_S
1433  INTEGER, SAVE :: IENT = 0
1434 #endif
1435  !/
1436  !/ ------------------------------------------------------------------- /
1437  !/
1438 #ifdef W3_S
1439  CALL strace (ient, 'J2D')
1440 #endif
1441 
1442  !
1443  IF(caltype .EQ. 'standard' .AND. julian .LT. 0.d0) THEN
1444  ! Negative Julian Day not allowed
1445  ierr=1
1446  RETURN
1447  END IF
1448 
1449  !CALL DATE_AND_TIME(values=TIMEZONE) ! Get the timezone
1450  !TZ=TIMEZONE(4)
1451  tz=0 ! Force to UTC timezone
1452 
1453  ! Calculation for time (hour,min,sec) same for Julian
1454  ! and 360_day calendars:
1455  ijul=idint(julian) ! Integral Julian Day
1456  second=sngl((julian-dble(ijul))*secday) ! Seconds from beginning of Jul. Day
1457  second=second+(tz*60)
1458 
1459  IF(caltype .EQ. "standard") THEN
1460  IF(second.GE.(secday/2.0d0)) THEN ! In next calendar day
1461  ijul=ijul+1
1462  second=second-(secday/2.0d0) ! Adjust from noon to midnight
1463  ELSE ! In same calendar day
1464  second=second+(secday/2.0d0) ! Adjust from noon to midnight
1465  END IF
1466  END IF
1467 
1468  IF(second.GE.secday) THEN ! Final check to prevent time 24:00:00
1469  ijul=ijul+1
1470  second=second-secday
1471  END IF
1472 
1473  minute=int(second/60.0) ! Integral minutes from beginning of day
1474  second=second-float(minute*60) ! Seconds from beginning of minute
1475  hour=minute/60 ! Integral hours from beginning of day
1476  minute=minute-hour*60 ! Integral minutes from beginning of hour
1477 
1478  IF(caltype .EQ. '360_day') THEN
1479  ! Calculate date parts for 360 day climate calendar
1480  year = int(julian / 360) + 1800 ! (base year is 1800)
1481  month = mod(int(julian / 30), 12) + 1
1482  day = mod(int(julian), 30) + 1
1483  ELSE ! Stardard Julian day calculation
1484  !---------------------------------------------
1485  jalpha=idint((dble(ijul-1867216)-0.25d0)/36524.25d0) ! Correction for Gregorian Calendar
1486  ja=ijul+1+jalpha-idint(0.25d0*dble(jalpha))
1487  !---------------------------------------------
1488 
1489  jb=ja+1524
1490  jc=idint(6680.d0+(dble(jb-2439870)-122.1d0)/365.25d0)
1491  jd=365*jc+idint(0.25d0*dble(jc))
1492  je=idint(dble(jb-jd)/30.6001d0)
1493  day=jb-jd-idint(30.6001d0*dble(je))
1494  month=je-1
1495 
1496  IF(month.GT.12) THEN
1497  month=month-12
1498  END IF
1499 
1500  year=jc-4715
1501  IF(month.GT.2) THEN
1502  year=year-1
1503  END IF
1504 
1505  IF(year.LE.0) THEN
1506  year=year-1
1507  END IF
1508  ENDIF
1509 
1510  dat(1)=year
1511  dat(2)=month
1512  dat(3)=day
1513  dat(4)=tz
1514  dat(5)=hour
1515  dat(6)=minute
1516  dat(7)=int(second)
1517  dat(8)=int((second-int(second))*1000.0)
1518  ierr=0
1519  !
1520  RETURN
1521  !/
1522  !/
1523  END SUBROUTINE j2d
1524 
1525  !/ ------------------------------------------------------------------- /
1526  DOUBLE PRECISION FUNCTION tsub ( T1, T2 )
1527  !/
1528  !/ +-----------------------------------+
1529  !/ | WAVEWATCH III NOAA/NCEP |
1530  !/ | M. Accensi |
1531  !/ | FORTRAN 90 |
1532  !/ | Last update : 18-Jun-2020 |
1533  !/ +-----------------------------------+
1534  !/
1535  !/ 15-May-2018 : Origination ( version 6.05 )
1536  !/ 18-Jun-2020 : Addition of 360-day calendar ( version 7.08 )
1537  !/
1538  ! 1. Purpose :
1539  !
1540  ! Substract two time arrays to get the time difference in days
1541  ! in a way to avoid decimal approximation error
1542  !
1543  ! 3. Parameters :
1544  !
1545  ! Parameter list
1546  ! ----------------------------------------------------------------
1547  ! T1 I.A. I Time array
1548  ! T2 I.A. I Time array
1549  ! ----------------------------------------------------------------
1550  !
1551  ! 4. Subroutines used :
1552  !
1553  ! Name Type Module Description
1554  ! ----------------------------------------------------------------
1555  ! STRACE Subr. W3SERVMD Subroutine tracing.
1556  ! ----------------------------------------------------------------
1557  !
1558  ! 5. Called by :
1559  !
1560  ! Any routine.
1561  !
1562  ! 10. Source code :
1563  !
1564  !/ ------------------------------------------------------------------- /
1565  !/
1566  IMPLICIT NONE
1567  !/
1568  !/ ------------------------------------------------------------------- /
1569  !/ Parameter list
1570  !/
1571  INTEGER, INTENT(IN) :: t1(8), t2(8)
1572  !/
1573  !/ ------------------------------------------------------------------- /
1574  !/ Local parameters
1575  !/
1576  INTEGER :: a1, b1, c1, d1, a2, b2, c2, d2
1577  DOUBLE PRECISION :: e1, e2
1578 #ifdef W3_S
1579  INTEGER, SAVE :: ient = 0
1580 #endif
1581  !/
1582  !/ ------------------------------------------------------------------- /
1583  !/
1584 #ifdef W3_S
1585  CALL strace (ient, 'TSUB')
1586 #endif
1587  !
1588  ! Convert dates and times :
1589  !
1590  IF (trim(caltype) .EQ. '360_day' ) THEN
1591  a1 = (t2(1)-t1(1))*360 + (t2(2)-t1(2))*30 + (t2(3)-t1(3))
1592 
1593  e1 = 3600.0*t1(5) + 60.0*(t1(6)-t1(4)) + t1(7) + t1(8)/1000.0
1594  e2 = 3600.0*t2(5) + 60.0*(t2(6)-t2(4)) + t2(7) + t2(8)/1000.0
1595  !
1596  tsub = dble(a1) + (e2-e1)/86400.0d0
1597  ELSE
1598  a1 = (14-t1(2))/12
1599  b1 = t1(1) + 4800 - a1
1600  c1 = t1(2) + 12*a1 - 3
1601  d1 = t1(3) + (153*c1 + 2)/5 + 365*b1
1602  IF (trim(caltype) .EQ. 'standard' ) THEN
1603  d1 = d1 + b1/4 -b1/100 + b1/400
1604  ENDIF
1605  e1 = 3600.0*t1(5) + 60.0*(t1(6)-t1(4)) + t1(7) + t1(8)/1000.0
1606  !
1607  a2 = (14-t2(2))/12
1608  b2 = t2(1) + 4800 - a2
1609  c2 = t2(2) + 12*a2 - 3
1610  d2 = t2(3) + (153*c2 + 2)/5 + 365*b2
1611  IF (trim(caltype) .EQ. 'standard' ) THEN
1612  d2 = d2 + b2/4 -b2/100 + b2/400
1613  ENDIF
1614  e2 = 3600.0*t2(5) + 60.0*(t2(6)-t2(4)) + t2(7) + t2(8)/1000.0
1615  !
1616  tsub = dble(d2-d1) + (e2-e1)/86400.0d0
1617  ENDIF
1618  !
1619  RETURN
1620  !/
1621  !/ End of TSUB ------------------------------------------------------- /
1622  !/
1623  END FUNCTION tsub
1624 
1625  !/ ------------------------------------------------------------------- /
1626  DOUBLE PRECISION FUNCTION tsubsec ( T1, T2 )
1627  !/
1628  !/ +-----------------------------------+
1629  !/ | WAVEWATCH III NOAA/NCEP |
1630  !/ | M. Accensi |
1631  !/ | C. Bunney |
1632  !/ | FORTRAN 90 |
1633  !/ | Last update : 18-Jun-2020 |
1634  !/ +-----------------------------------+
1635  !/
1636  !/ 15-May-2018 : Origination (adapted from TSUB) ( version 7.12 )
1637  !/
1638  ! 1. Purpose :
1639  !
1640  ! Substract two time arrays to get the time difference in seconds.
1641  ! The milliseconds part of the array (index 8) is rounded to the
1642  ! nearest whole second.
1643  !
1644  ! 3. Parameters :
1645  !
1646  ! Parameter list
1647  ! ----------------------------------------------------------------
1648  ! T1 I.A. I Time array
1649  ! T2 I.A. I Time array
1650  ! ----------------------------------------------------------------
1651  !
1652  ! 4. Subroutines used :
1653  !
1654  ! Name Type Module Description
1655  ! ----------------------------------------------------------------
1656  ! STRACE Subr. W3SERVMD Subroutine tracing.
1657  ! ----------------------------------------------------------------
1658  !
1659  ! 5. Called by :
1660  !
1661  ! Any routine.
1662  !
1663  ! 10. Source code :
1664  !
1665  !/ ------------------------------------------------------------------- /
1666  !/
1667  IMPLICIT NONE
1668  !/
1669  !/ ------------------------------------------------------------------- /
1670  !/ Parameter list
1671  !/
1672  INTEGER, INTENT(IN) :: t1(8), t2(8)
1673  !/
1674  !/ ------------------------------------------------------------------- /
1675  !/ Local parameters
1676  !/
1677  INTEGER(KIND=8) :: a1, b1, c1, d1, a2, b2, c2, d2
1678  INTEGER(KIND=8) :: e1, e2
1679 #ifdef W3_S
1680  INTEGER, SAVE :: ient = 0
1681 #endif
1682  !/
1683  !/ ------------------------------------------------------------------- /
1684  !/
1685 #ifdef W3_S
1686  CALL strace (ient, 'TSUBSEC')
1687 #endif
1688  !
1689  IF (trim(caltype) .EQ. '360_day' ) THEN
1690  a1 = (t2(1)-t1(1))*360 + (t2(2)-t1(2))*30 + (t2(3)-t1(3))
1691 
1692  e1 = 3600.0*t1(5) + 60.0*(t1(6)-t1(4)) + t1(7) + nint(t1(8) / 1000.0)
1693  e2 = 3600.0*t2(5) + 60.0*(t2(6)-t2(4)) + t2(7) + nint(t2(8) / 1000.0)
1694  !
1695  tsubsec = a1 * 86400 + (e2-e1)
1696  ELSE
1697  a1 = (14-t1(2))/12
1698  b1 = t1(1) + 4800 - a1
1699  c1 = t1(2) + 12*a1 - 3
1700  d1 = t1(3) + (153*c1 + 2)/5 + 365*b1
1701  IF (trim(caltype) .EQ. 'standard' ) THEN
1702  d1 = d1 + b1/4 -b1/100 + b1/400
1703  ENDIF
1704  e1 = 3600.0*t1(5) + 60.0*(t1(6)-t1(4)) + t1(7) + nint(t1(8) / 1000.0)
1705  !
1706  a2 = (14-t2(2))/12
1707  b2 = t2(1) + 4800 - a2
1708  c2 = t2(2) + 12*a2 - 3
1709  d2 = t2(3) + (153*c2 + 2)/5 + 365*b2
1710  IF (trim(caltype) .EQ. 'standard' ) THEN
1711  d2 = d2 + b2/4 -b2/100 + b2/400
1712  ENDIF
1713  e2 = 3600.0*t2(5) + 60.0*(t2(6)-t2(4)) + t2(7) + nint(t1(8) / 1000.0)
1714  !
1715  tsubsec = (d2-d1)*86400 + (e2-e1)
1716  ENDIF
1717  !
1718  RETURN
1719  !/
1720  !/ End of TSUBSEC ---------------------------------------------------- /
1721  !/
1722  END FUNCTION tsubsec
1723 
1724 
1725  !/ ------------------------------------------------------------------- /
1726 
1727  SUBROUTINE u2d(UNITS,DAT,IERR)
1728  !/
1729  !/ +-----------------------------------+
1730  !/ | WAVEWATCH III NOAA/NCEP |
1731  !/ | M. Accensi |
1732  !/ | FORTRAN 90 |
1733  !/ | Last update : 15-May-2018 |
1734  !/ +-----------------------------------+
1735  !/
1736  !/ 15-May-2018 : Origination ( version 6.05 )
1737  !/
1738  ! 1. Purpose :
1739  !
1740  ! Convert time units attribute to date array
1741  !
1742  ! * units attribute must respect convention ISO8601
1743  !
1744  ! 3. Parameters :
1745  !
1746  ! Parameter list
1747  ! ----------------------------------------------------------------
1748  ! UNITS Char I Units attribute
1749  ! DAT I.A. O Time array like returned by DATE_AND_TIME(3f)
1750  ! IERR Integer O Error code returned
1751  ! ----------------------------------------------------------------
1752  !
1753  ! 4. Subroutines used :
1754  !
1755  ! Name Type Module Description
1756  ! ----------------------------------------------------------------
1757  ! STRACE Subr. W3SERVMD Subroutine tracing.
1758  ! ----------------------------------------------------------------
1759  !
1760  ! 5. Called by :
1761  !
1762  ! Any subroutine/program.
1763  !
1764  ! 10. Source code :
1765  !
1766  !/ ------------------------------------------------------------------- /
1767  !/
1768  USE w3servmd, ONLY: extcde
1769  USE w3odatmd, ONLY: ndse
1770  !
1771  IMPLICIT NONE
1772  !/
1773  !/ ------------------------------------------------------------------- /
1774  !/ Parameter list
1775  !/
1776  CHARACTER(*),INTENT(IN) :: UNITS ! Units attribute
1777  INTEGER,INTENT(OUT) :: DAT(8) ! array like returned by DATE_AND_TIME(3f)
1778  INTEGER,INTENT(OUT) :: IERR ! Error return, 0 for successful execution
1779  ! Otherwise returnb 1
1780  !/
1781  !/ ------------------------------------------------------------------- /
1782  !/ Local parameters
1783  !/
1784 #ifdef W3_S
1785  INTEGER, SAVE :: IENT = 0
1786 #endif
1787  !/
1788  !/ ------------------------------------------------------------------- /
1789  !/
1790 #ifdef W3_S
1791  CALL strace (ient, 'U2D')
1792 #endif
1793  !
1794 
1795  dat(4) = 0 ! force to UTC timezone
1796  dat(8) = 0 ! force milliseconds to 0
1797 
1798 
1799  ! seconds
1800  IF (index(units, "seconds").NE.0) THEN
1801  ! seconds since YYYY-MM-DD hh:mm:ss
1802  IF (index(units, "-", .true.).EQ.22) THEN
1803  READ(units(15:18),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1804  READ(units(20:21),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1805  READ(units(23:24),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1806  READ(units(26:27),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1807  READ(units(29:30),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1808  READ(units(32:33),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1809  ! seconds since YYYY-M-D ...
1810  ELSE IF (index(units, "-", .true.).EQ.21) THEN
1811  READ(units(15:18),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1812  READ(units(20:20),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1813  READ(units(22:22),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1814  ! seconds since YYYY-M-D h:m:s
1815  IF (index(units, ":", .false.).EQ.25) THEN
1816  READ(units(24:24),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1817  READ(units(26:26),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1818  READ(units(28:28),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1819  ! seconds since YYYY-M-D hh:mm:ss
1820  ELSE IF (index(units, ":", .false.).EQ.26) THEN
1821  READ(units(24:25),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1822  READ(units(27:28),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1823  READ(units(30:31),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1824  ELSE
1825  GOTO 804
1826  END IF
1827  ELSE
1828  GOTO 804
1829  END IF
1830 
1831  ! days
1832  ELSE IF (index(units, "days").NE.0) THEN
1833  ! days since YYYY-MM-DD hh:mm:ss
1834  IF (index(units, "-", .true.).EQ.19) THEN
1835  READ(units(12:15),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1836  READ(units(17:18),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1837  READ(units(20:21),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1838  READ(units(23:24),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1839  READ(units(26:27),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1840  READ(units(29:30),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1841  ! days since YYYY-M-D ...
1842  ELSE IF (index(units, "-", .true.).EQ.18) THEN
1843  READ(units(12:15),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1844  READ(units(17:17),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1845  READ(units(19:19),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1846  ! days since YYYY-M-D h:m:s
1847  IF (index(units, ":", .false.).EQ.22) THEN
1848  READ(units(21:21),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1849  READ(units(23:23),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1850  READ(units(25:25),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1851  ! days since YYYY-M-D hh:mm:ss
1852  ELSE IF (index(units, ":", .false.).EQ.23) THEN
1853  READ(units(21:22),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1854  READ(units(24:25),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1855  READ(units(27:28),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1856  ELSE
1857  GOTO 804
1858  END IF
1859  ELSE
1860  GOTO 804
1861  END IF
1862 
1863  ! hours
1864  ELSE IF (index(units, "hours").NE.0) THEN
1865  ! hours since YYYY-MM-DD hh:mm:ss
1866  IF (index(units, "-", .true.).EQ.20) THEN
1867  READ(units(13:16),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1868  READ(units(18:19),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1869  READ(units(21:22),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1870  READ(units(24:25),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1871  READ(units(27:28),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1872  READ(units(30:31),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1873  ! hours since YYYY-M-D ...
1874  ELSE IF (index(units, "-", .true.).EQ.19) THEN
1875  READ(units(13:16),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1876  READ(units(18:18),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1877  READ(units(20:20),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1878  ! hours since YYYY-M-D h:m:s
1879  IF (index(units, ":", .false.).EQ.23) THEN
1880  READ(units(22:22),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1881  READ(units(24:24),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1882  READ(units(26:26),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1883  ! hours since YYYY-M-D hh:mm:ss
1884  ELSE IF (index(units, ":", .false.).EQ.24) THEN
1885  READ(units(22:23),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1886  READ(units(25:26),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1887  READ(units(28:29),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1888  ELSE
1889  GOTO 804
1890  END IF
1891  ELSE
1892  GOTO 804
1893  END IF
1894 
1895  ! minutes
1896  ELSE IF (index(units, "minutes").NE.0) THEN
1897  ! minutes since YYYY-MM-DD hh:mm:ss
1898  IF (index(units, "-", .true.).EQ.22) THEN
1899  READ(units(15:18),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1900  READ(units(20:21),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1901  READ(units(23:24),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1902  READ(units(26:27),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1903  READ(units(29:30),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1904  READ(units(32:33),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1905  ! minutes since YYYY-M-D ...
1906  ELSE IF (index(units, "-", .true.).EQ.21) THEN
1907  READ(units(15:18),'(I4.4)',END=804,ERR=805,IOSTAT=IERR) DAT(1)
1908  READ(units(20:20),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(2)
1909  READ(units(22:22),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(3)
1910  ! minutes since YYYY-M-D h:m:s
1911  IF (index(units, ":", .false.).EQ.25) THEN
1912  READ(units(24:24),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1913  READ(units(26:26),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1914  READ(units(28:28),'(I1.1)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1915  ! minutes since YYYY-M-D hh:mm:ss
1916  ELSE IF (index(units, ":", .false.).EQ.26) THEN
1917  READ(units(24:25),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(5)
1918  READ(units(27:28),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(6)
1919  READ(units(30:31),'(I2.2)',END=804,ERR=805,IOSTAT=IERR) DAT(7)
1920  ELSE
1921  GOTO 804
1922  END IF
1923  ELSE
1924  GOTO 804
1925  END IF
1926 
1927  ! nothing
1928  ELSE
1929  GOTO 804
1930  END IF
1931  !
1932  GOTO 888
1933  !
1934  ! Error escape locations
1935  !
1936 804 CONTINUE
1937  WRITE (ndse,1004) trim(units)
1938  CALL extcde ( 44 )
1939  !
1940 805 CONTINUE
1941  WRITE (ndse,1005) ierr
1942  CALL extcde ( 45 )
1943  !
1944 888 CONTINUE
1945 
1946  !
1947  ! Formats
1948  !
1949 1004 FORMAT (/' *** WAVEWATCH III ERROR IN W3TIMEMD : '/ &
1950  ' PREMATURE END OF TIME ATTRIBUTE '/ &
1951  ' ',a/ &
1952  ' DIFFERS FROM CONVENTIONS ISO8601 '/ &
1953  ' XXX since YYYY-MM-DD hh:mm:ss'/ &
1954  ' XXX since YYYY-M-D h:m:s'/ &
1955  ' XXX since YYYY-M-D hh:mm:ss'/)
1956  !
1957 1005 FORMAT (/' *** WAVEWATCH III ERROR IN W3TIMEMD : '/ &
1958  ' ERROR IN READING OF TIME ATTRIBUTE '/ &
1959  ' ',a/ &
1960  ' DIFFERS FROM CONVENTIONS ISO8601 '/ &
1961  ' XXX since YYYY-MM-DD hh:mm:ss'/ &
1962  ' XXX since YYYY-M-D h:m:s'/ &
1963  ' XXX since YYYY-M-D hh:mm:ss'/ &
1964  ' IOSTAT =',i5/)
1965  !
1966  RETURN
1967  !/
1968  !/ End of U2D ----------------------------------------------------- /
1969  !/
1970  END SUBROUTINE u2d
1971 
1972 
1973  !/ ------------------------------------------------------------------- /
1974 
1975  !/ ------------------------------------------------------------------- /
1976 
1977  SUBROUTINE t2iso(TIME,ISODT)
1978  !/
1979  !/ +-----------------------------------+
1980  !/ | WAVEWATCH III NOAA/NCEP |
1981  !/ | C. Bunney |
1982  !/ | FORTRAN 90 |
1983  !/ | Last update : 19-Jan-2020 |
1984  !/ +-----------------------------------+
1985  !/
1986  !/ 19-Jan-2020 : Origination ( version 7.12 )
1987  !/
1988  ! 1. Purpose :
1989  !
1990  ! Convert time array to ISO8601 format string
1991  !
1992  ! 3. Parameters :
1993  !
1994  ! Parameter list
1995  ! ----------------------------------------------------------------
1996  ! TIME I.A. I Time array like 'YYYYMMDD HHMMSS'
1997  ! ISODT Char. O ISO8601 datetime string
1998  ! ----------------------------------------------------------------
1999  !
2000  ! 4. Subroutines used :
2001  !
2002  ! Name Type Module Description
2003  ! ----------------------------------------------------------------
2004  ! STRACE Subr. W3SERVMD Subroutine tracing.
2005  ! ----------------------------------------------------------------
2006  !
2007  ! 5. Called by :
2008  !
2009  ! Any subroutine/program.
2010  !
2011  ! 10. Source code :
2012  !
2013  !/ ------------------------------------------------------------------- /
2014  !/
2015  USE w3servmd, ONLY: extcde
2016  USE w3odatmd, ONLY: ndse
2017  !
2018  IMPLICIT NONE
2019  !/
2020  !/ ------------------------------------------------------------------- /
2021  !/ Parameter list
2022  !/
2023  INTEGER,INTENT(IN) :: TIME(2) ! array like 'YYYYMMDD HHMMSS'
2024  CHARACTER(LEN=32),INTENT(OUT) :: ISODT ! ISO date time
2025  !/
2026  !/ ------------------------------------------------------------------- /
2027  !/ Local parameters
2028  !/
2029 #ifdef W3_S
2030  INTEGER, SAVE :: IENT = 0
2031 #endif
2032  !/
2033  !/ ------------------------------------------------------------------- /
2034  !/
2035 #ifdef W3_S
2036  CALL strace (ient, 'T2ISO')
2037 #endif
2038  !
2039  !/
2040  WRITE(isodt,'(I4,"-",I2.2,"-",I2.2,"T",I2.2,":",I2.2,":",I2.2)') &
2041  time(1) / 10000, &
2042  mod(time(1) / 100, 100), &
2043  mod(time(1), 100), &
2044  time(2) / 10000, &
2045  mod(time(2) / 100, 100), &
2046  mod(time(2), 100)
2047  !/
2048  !/ End of T2ISO ------------------------------------------------------ /
2049  !/
2050  END SUBROUTINE t2iso
2051 
2052  !/ End of module W3TIMEMD -------------------------------------------- /
2053  !/
2054 END MODULE w3timemd
w3timemd::dsec21
real function dsec21(TIME1, TIME2)
Definition: w3timemd.F90:333
w3timemd::t2d
subroutine t2d(TIME, DAT, IERR)
Definition: w3timemd.F90:1072
w3timemd::tdiff
real function tdiff(T1, T2)
Definition: w3timemd.F90:576
mymd21
integer function mymd21(NYMD)
Definition: w3timemd.F90:460
iymd21
integer function iymd21(NYMD, M)
Definition: w3timemd.F90:198
w3timemd::tsubsec
double precision function tsubsec(T1, T2)
Definition: w3timemd.F90:1627
w3timemd::j2d
subroutine j2d(JULIAN, DAT, IERR)
Definition: w3timemd.F90:1368
w3timemd::t2iso
subroutine t2iso(TIME, ISODT)
Definition: w3timemd.F90:1978
w3odatmd::ndse
integer, pointer ndse
Definition: w3odatmd.F90:456
w3timemd::d2j
subroutine d2j(DAT, JULIAN, IERR)
Definition: w3timemd.F90:1227
w3servmd
Definition: w3servmd.F90:3
w3timemd::tick21
subroutine tick21(TIME, DTIME)
Definition: w3timemd.F90:84
w3timemd::caltype
character, public caltype
Definition: w3timemd.F90:79
w3timemd::caldat
subroutine caldat(julian, id, mm, iyyy)
Definition: w3timemd.F90:800
w3timemd::stme21
subroutine stme21(TIME, DTME21)
Definition: w3timemd.F90:682
w3odatmd
Definition: w3odatmd.F90:3
w3timemd::prinit
subroutine prinit
Definition: w3timemd.F90:930
w3timemd::tsub
double precision function tsub(T1, T2)
Definition: w3timemd.F90:1527
w3timemd::d2t
subroutine d2t(DAT, TIME, IERR)
Definition: w3timemd.F90:1153
w3timemd::prtime
subroutine prtime(PTIME)
Definition: w3timemd.F90:990
w3servmd::strace
subroutine strace(IENT, SNAME)
Definition: w3servmd.F90:148
w3timemd::u2d
subroutine u2d(UNITS, DAT, IERR)
Definition: w3timemd.F90:1728
w3servmd::extcde
subroutine extcde(IEXIT, UNIT, MSG, FILE, LINE, COMM)
Definition: w3servmd.F90:736
w3timemd::julday
integer function julday(id, mm, iyyy)
Definition: w3timemd.F90:756
w3timemd
Definition: w3timemd.F90:3
w3timemd::time2hours
real(kind=8) function time2hours(TIME)
Definition: w3timemd.F90:844