62 module time_manager_mod
65 use platform_mod,
only: r8_kind, r4_kind
66 use constants_mod,
only: rseconds_per_day=>seconds_per_day
76 public operator(+),
operator(-),
operator(*),
operator(/), &
77 operator(>),
operator(>=),
operator(==),
operator(/=), &
78 operator(<),
operator(<=),
operator(//),
assignment(=)
86 public thirty_day_months, julian, gregorian, noleap, no_calendar, invalid_calendar
116 public :: set_date_julian, set_date_no_leap, get_date_julian, get_date_no_leap
123 integer,
parameter :: THIRTY_DAY_MONTHS = 1, julian = 2, &
124 gregorian = 3, noleap = 4, &
125 no_calendar = 0, invalid_calendar =-1
126 integer,
private :: calendar_type = no_calendar
127 integer,
parameter :: max_type = 4
130 integer,
private :: days_per_month(12) = (/31,28,31,30,31,30,31,31,30,31,30,31/)
131 integer,
parameter :: seconds_per_day = rseconds_per_day
133 integer,
parameter :: do_floor = 0
134 integer,
parameter :: do_nearest = 1
150 interface operator (+); module
procedure time_plus; end interface
153 interface operator (-); module
procedure time_minus; end interface
156 interface operator (*); module
procedure time_scalar_mult
160 interface operator (/); module
procedure time_scalar_divide
164 interface operator (>); module
procedure time_gt; end interface
167 interface operator (>=); module
procedure time_ge; end interface
170 interface operator (<); module
procedure time_lt; end interface
173 interface operator (<=); module
procedure time_le; end interface
176 interface operator (==); module
procedure time_eq; end interface
179 interface operator (/=); module
procedure time_ne; end interface
182 interface operator (//); module
procedure time_real_divide; end interface
185 interface assignment(=); module
procedure time_assignment; end interface
265 #include<file_version.h>
266 logical :: module_is_initialized = .false.
273 integer :: ticks_per_second = 1
303 integer,
intent(in) :: seconds, days, ticks
305 character(len=*),
intent(out) :: err_msg
306 integer :: seconds_new, days_new, ticks_new
308 seconds_new = seconds + floor(real(ticks, r8_kind)/real(ticks_per_second, r8_kind))
309 ticks_new = modulo(ticks,ticks_per_second)
310 days_new = days + floor(real(seconds_new, r8_kind)/real(seconds_per_day, r8_kind))
311 seconds_new = modulo(seconds_new,seconds_per_day)
313 if ( seconds_new < 0 .or. ticks_new < 0)
then
314 call error_mesg(
'function set_time_i',
'Bad result for time. Contact those responsible for maintaining time_manager'&
318 if(days_new < 0)
then
319 write(err_msg,
'(a,i6,a,i6,a,i6)')
'time is negative. days=',days_new,
' seconds=',seconds_new,
' ticks=',ticks_new
322 time_out%days = days_new
323 time_out%seconds = seconds_new
324 time_out%ticks = ticks_new
334 integer,
intent(in) :: seconds
335 integer,
intent(in),
optional :: days
336 integer,
intent(in),
optional :: ticks
337 character(len=*),
intent(out),
optional :: err_msg
343 character(len=128) :: err_msg_local
344 integer :: odays, oticks
348 odays = 0;
if(
present(days)) odays = days
349 oticks = 0;
if(
present(ticks)) oticks = ticks
350 if(
present(err_msg)) err_msg =
''
353 if(error_handler(
'function set_time_i', trim(err_msg_local), err_msg))
return
363 character(len=*),
intent(in) :: string
366 character(len=*),
intent(out),
optional :: err_msg
372 logical,
intent(in),
optional :: allow_rounding
376 character(len=4) :: formt=
'(i )'
377 integer :: i1, i2, i3, day, second, tick, nsps
378 character(len=32) :: string_sifted_left
379 character(len=128) :: err_msg_local
380 logical :: allow_rounding_local
383 if(
present(err_msg)) err_msg =
''
384 allow_rounding_local=.true.;
if(
present(allow_rounding)) allow_rounding_local=allow_rounding
386 err_msg_local =
'Form of character time stamp is incorrect. The character time stamp is: '//trim(string)
388 string_sifted_left = adjustl(string)
389 i1 = index(trim(string_sifted_left),
' ')
391 if(error_handler(
'function set_time_c', err_msg_local, err_msg))
return
393 if(index(string,
'-') /= 0 .or. index(string,
':') /= 0)
then
394 if(error_handler(
'function set_time_c', err_msg_local, err_msg))
return
397 i2 = index(trim(string_sifted_left),
'.')
398 i3 = len_trim(cut0(string_sifted_left))
403 if(error_handler(
'function set_time_c', err_msg_local, err_msg))
return
406 write(formt(3:3),
'(i1)') i1-1
407 read(string_sifted_left(1:i1-1),formt) day
410 write(formt(3:3),
'(i1)') i3-i1
411 read(string_sifted_left(i1+1:i3),formt) second
419 write(formt(3:3),
'(i1)') nsps
420 read(string_sifted_left(i1+1:i2-1),formt) second
423 if(.not.get_tick_from_string(string_sifted_left(i2:i3), err_msg_local, allow_rounding_local, tick))
then
424 if(error_handler(
'function set_time_c', err_msg_local, err_msg))
return
427 if(tick == ticks_per_second)
then
434 if(error_handler(
'function set_time_c', err_msg_local, err_msg))
return
440 function get_tick_from_string(string, err_msg, allow_rounding, tick)
442 logical :: get_tick_from_string
443 character(len=*),
intent(in) :: string
444 character(len=*),
intent(out) :: err_msg
445 logical,
intent(in) :: allow_rounding
446 integer,
intent(out) :: tick
448 character(len=4) :: formt=
'(i )'
449 integer :: i3, nspf, fraction, magnitude, tpsfrac
452 get_tick_from_string = .true.
453 i3 = len_trim(string)
458 write(formt(3:3),
'(i1)') nspf
459 read(string(2:i3),formt) fraction
460 if(fraction == 0)
then
464 tpsfrac = ticks_per_second*fraction
465 if(allow_rounding)
then
466 tick = nint((real(tpsfrac, r8_kind)/real(magnitude, r8_kind)))
468 if(modulo(tpsfrac,magnitude) == 0)
then
469 tick = tpsfrac/magnitude
471 write(err_msg,
'(a,i6)')
'Second fraction cannot be exactly represented with ticks. '// &
472 'fraction='//trim(string)//
' ticks_per_second=',ticks_per_second
473 get_tick_from_string = .false.
479 end function get_tick_from_string
491 subroutine get_time(Time, seconds, days, ticks, err_msg)
496 integer,
intent(out) :: seconds
497 integer,
intent(out),
optional :: days, ticks
498 character(len=*),
intent(out),
optional :: err_msg
499 character(len=128) :: err_msg_local
502 if(
present(err_msg)) err_msg =
''
504 seconds = time%seconds
506 if(
present(ticks))
then
509 if(time%ticks /= 0)
then
510 err_msg_local =
'subroutine get_time: ticks must be present when time has a second fraction'
511 if(error_handler(
'subroutine get_time', err_msg_local, err_msg))
return
515 if (
present(days))
then
518 if (time%days > (huge(seconds) - seconds)/seconds_per_day)
then
519 err_msg_local =
'Integer overflow in seconds. Optional argument days must be present.'
520 if(error_handler(
'subroutine get_time', err_msg_local, err_msg))
return
522 seconds = seconds + time%days * seconds_per_day
536 integer,
intent(in) :: seconds
537 integer,
intent(in),
optional :: days, ticks
538 character(len=*),
intent(out),
optional :: err_msg
541 logical,
intent(in),
optional :: allow_neg_inc
543 integer :: odays, oticks
544 character(len=128) :: err_msg_local
545 logical :: allow_neg_inc_local
547 odays = 0;
if(
present(days)) odays = days
548 oticks = 0;
if(
present(ticks)) oticks = ticks
549 allow_neg_inc_local=.true.;
if(
present(allow_neg_inc)) allow_neg_inc_local=allow_neg_inc
551 if(.not.allow_neg_inc_local)
then
552 if(seconds < 0 .or. odays < 0 .or. oticks < 0)
then
553 write(err_msg_local,10) seconds, odays, oticks
554 10
format(
'One or more time increments are negative: seconds=',i6,
' days=',i6,
' ticks=',i6)
555 if(error_handler(
'function increment_time', err_msg_local, err_msg))
return
560 if(error_handler(
'function increment_time', err_msg_local, err_msg))
return
572 integer,
intent(in) :: seconds, days, ticks
574 character(len=*),
intent(out) :: err_msg
577 if(days >= huge(days) - time_in%days)
then
578 err_msg =
'Integer overflow in days in increment_time'
582 if(seconds >= huge(seconds) - time_in%seconds)
then
583 err_msg =
'Integer overflow in seconds in increment_time'
606 integer,
intent(in) :: seconds
607 integer,
intent(in),
optional :: days, ticks
608 character(len=*),
intent(out),
optional :: err_msg
610 logical,
intent(in),
optional :: allow_neg_inc
614 integer :: odays, oticks
615 character(len=128) :: err_msg_local
616 logical :: allow_neg_inc_local
618 odays = 0;
if (
present(days)) odays = days
619 oticks = 0;
if (
present(ticks)) oticks = ticks
620 allow_neg_inc_local=.true.;
if(
present(allow_neg_inc)) allow_neg_inc_local=allow_neg_inc
622 if(.not.allow_neg_inc_local)
then
623 if(seconds < 0 .or. odays < 0 .or. oticks < 0)
then
624 write(err_msg_local,10) seconds,odays,oticks
625 10
format(
'One or more time increments are negative: seconds=',i6,
' days=',i6,
' ticks=',i6)
626 if(error_handler(
'function decrement_time', err_msg_local, err_msg))
return
631 if(error_handler(
'function decrement_time', err_msg_local, err_msg))
return
639 function time_gt(time1, time2)
645 time_gt = (time1%days > time2%days)
646 if(time1%days == time2%days)
then
647 if(time1%seconds == time2%seconds)
then
648 time_gt = (time1%ticks > time2%ticks)
650 time_gt = (time1%seconds > time2%seconds)
659 function time_ge(time1, time2)
664 time_ge = (time_gt(time1, time2) .or. time_eq(time1, time2))
671 function time_lt(time1, time2)
676 time_lt = (time1%days < time2%days)
677 if(time1%days == time2%days)
then
678 if(time1%seconds == time2%seconds)
then
679 time_lt = (time1%ticks < time2%ticks)
681 time_lt = (time1%seconds < time2%seconds)
689 function time_le(time1, time2)
694 time_le = (time_lt(time1, time2) .or. time_eq(time1, time2))
701 function time_eq(time1, time2)
708 time_eq = (time1%seconds == time2%seconds .and. time1%days == time2%days &
709 .and. time1%ticks == time2%ticks)
716 function time_ne(time1, time2)
721 time_ne = (.not. time_eq(time1, time2))
728 function time_plus(time1, time2)
735 time_plus =
increment_time(time1, time2%seconds, time2%days, time2%ticks)
737 end function time_plus
743 function time_minus(time1, time2)
750 if(time1 > time2)
then
751 time_minus =
decrement_time(time1, time2%seconds, time2%days, time2%ticks)
753 time_minus =
decrement_time(time2, time1%seconds, time1%days, time1%ticks)
756 end function time_minus
764 integer,
intent(in) :: n
765 integer :: days, seconds, ticks, num_sec
766 real(r8_kind) :: sec_prod, tick_prod
775 tick_prod = real(time%ticks, r8_kind) * real(n, r8_kind)
776 num_sec = int(tick_prod/real(ticks_per_second, r8_kind))
777 sec_prod = real(time%seconds, r8_kind) * real(n, r8_kind) + real(num_sec, r8_kind)
778 ticks = int(tick_prod) - (num_sec * ticks_per_second)
785 if(sec_prod /= 0.0_r8_kind)
then
786 if(log10(sec_prod) > precision(sec_prod) - 3)
call error_mesg(
'time_scalar_mult', &
787 'Insufficient precision to handle scalar product in time_scalar_mult; contact developer',fatal)
790 days = int(sec_prod / real(seconds_per_day, r8_kind))
791 seconds = int(sec_prod - real(days, r8_kind) * real(seconds_per_day, r8_kind))
804 integer,
intent(in) :: n
818 real(r8_kind) :: d1, d2
823 d1 = real(time1%days, r8_kind) * real(seconds_per_day, r8_kind) + real(time1%seconds, r8_kind) &
824 + real(time1%ticks, r8_kind)/real(ticks_per_second, r8_kind)
825 d2 = real(time2%days, r8_kind) * real(seconds_per_day, r8_kind) + real(time2%seconds, r8_kind) &
826 + real(time2%ticks,r8_kind)/real(ticks_per_second, r8_kind)
833 call error_mesg(
'time_divide',
' quotient error :: notify developer',fatal)
838 function time_real_divide(time1, time2)
840 real(r8_kind) :: time_real_divide
843 real(r8_kind) :: d1, d2
848 d1 = real(time1%days, r8_kind) * real(seconds_per_day, r8_kind) + real(time1%seconds, r8_kind) + &
849 real(time1%ticks, r8_kind)/
real(ticks_per_second, r8_kind)
850 d2 = real(time2%days, r8_kind) * real(seconds_per_day, r8_kind) + real(time2%seconds, r8_kind) + &
851 real(time2%ticks, r8_kind)/
real(ticks_per_second, r8_kind)
853 time_real_divide = d1 / d2
855 end function time_real_divide
861 subroutine time_assignment(time1, time2)
864 time1%seconds = time2%seconds
865 time1%days = time2%days
866 time1%ticks = time2%ticks
867 end subroutine time_assignment
877 time_type_to_real = real(time%days, r8_kind) * 86400.e0_r8_kind + real(time%seconds, r8_kind) + &
878 real(time%ticks, r8_kind)/
real(ticks_per_second, r8_kind)
886 real(r8_kind),
intent(in) :: x
887 character(len=*),
intent(out),
optional :: err_msg
892 character(len=128) :: err_msg_local
893 real(r8_kind),
parameter :: spd = 86400.0_r8_kind
896 tps = real(ticks_per_second, r8_kind)
899 a = x - real(days, r8_kind)*spd
901 a = (a - real(seconds, r8_kind))*tps
904 if (error_handler(
'function real8_to_time_type',err_msg_local,err_msg))
then
911 real(r4_kind),
intent(in) :: x
912 character(len=*),
intent(out),
optional :: err_msg
920 real(r8_kind),
intent(in) :: rval
921 integer,
intent(in) :: mode
925 big = real(huge(ival), r8_kind)
926 if (rval .le. big .and. -1.0_r8_kind*rval .ge. -1.0_r8_kind*big)
then
927 if (mode .eq. do_floor)
then
929 elseif (mode .eq. do_nearest)
then
932 call error_mesg(
"safe_rtoi",
"mode must be either do_floor" &
933 //
" or do_nearest.",fatal)
936 call error_mesg(
"safe_rtoi",
"input value cannot be safely" &
937 //
" converted to a 32-bit integer.",fatal)
947 integer,
intent(in) :: n
948 real(r8_kind) :: d, div, dseconds_per_day, dticks_per_second
949 integer :: days, seconds, ticks
951 character(len=128) tmp1,tmp2
955 dseconds_per_day = real(seconds_per_day, r8_kind)
956 dticks_per_second = real(ticks_per_second, r8_kind)
957 d = real(time%days,r8_kind)*dseconds_per_day*dticks_per_second + real(time%seconds, r8_kind)*dticks_per_second + &
958 real(time%ticks, r8_kind)
959 div = d/real(n, r8_kind)
961 days = int(div/(dseconds_per_day*dticks_per_second))
962 seconds = int(div/dticks_per_second - real(days, r8_kind)*dseconds_per_day)
963 ticks = int(div - (real(days, r8_kind)*dseconds_per_day + real(seconds, r8_kind))*dticks_per_second)
969 if(prod1 > time .or. prod2 <= time)
then
970 call get_time(time, seconds, days, ticks)
971 write(tmp1,20) days,seconds,ticks
973 write(tmp2,30) n,days,seconds,ticks
974 ltmp = error_handler(
'time_scalar_divide',
' quotient error:'//trim(tmp1)//trim(tmp2))
975 20
format(
'time=',i7,
' days, ',i6,
' seconds, ',i6,
' ticks')
976 30
format(
' time divided by',i6,
'=',i7,
' days, ',i6,
' seconds, ',i6,
' ticks')
1003 type(
time_type),
intent(in) :: time_interval
1004 type(
time_type),
intent(in) :: alarm_interval
1008 if((alarm - time) <= (time_interval / 2))
then
1010 alarm = alarm + alarm_interval
1028 type(
time_type),
intent(in) :: alarm_frequency
1029 type(
time_type),
intent(in) :: alarm_length
1032 prev = (time / alarm_frequency) * alarm_frequency
1033 next = prev + alarm_frequency
1034 if(time - prev <= alarm_length / 2 .or. next - time <= alarm_length / 2)
then
1078 integer,
intent(in) ::
type
1079 character(len=*),
intent(out),
optional :: err_msg
1080 character(len=256) :: err_msg_local
1084 if(
present(err_msg)) err_msg =
''
1086 if(
type < 0 .or. type > max_type)
then
1087 err_msg_local =
'Illegal calendar type'
1088 if(error_handler(
'subroutine set_calendar_type', err_msg_local, err_msg))
return
1091 if(seconds_per_day /= 86400 .and.
type /= no_calendar )
then
1092 err_msg_local =
'Only calendar type NO_CALENDAR is allowed when seconds_per_day is not 86400.'// &
1094 write(err_msg_local(len_trim(err_msg_local)+1:len_trim(err_msg_local)+8),
'(i8)') seconds_per_day
1095 if(error_handler(
'subroutine set_calendar_type', err_msg_local, err_msg))
return
1098 calendar_type =
type
1117 integer,
intent(in) :: tps
1119 ticks_per_second = tps
1145 subroutine get_date(time, year, month, day, hour, minute, second, tick, err_msg)
1150 integer,
intent(out) :: second, minute, hour, day, month, year
1151 integer,
intent(out),
optional :: tick
1152 character(len=*),
intent(out),
optional :: err_msg
1153 character(len=128) :: err_msg_local
1157 if(
present(err_msg)) err_msg =
''
1159 select case(calendar_type)
1160 case(thirty_day_months)
1161 call get_date_thirty(time, year, month, day, hour, minute, second, tick1)
1167 call get_date_no_leap_private(time, year, month, day, hour, minute, second, tick1)
1169 err_msg_local =
'Cannot produce a date when the calendar type is NO_CALENDAR'
1170 if(error_handler(
'subroutine get_date', err_msg_local, err_msg))
return
1172 err_msg_local =
'Invalid calendar type'
1173 if(error_handler(
'subroutine get_date', err_msg_local, err_msg))
return
1176 if(
present(tick))
then
1180 err_msg_local =
'tick must be present when time has a second fraction'
1181 if(error_handler(
'subroutine get_date', err_msg_local, err_msg))
return
1194 integer,
intent(out) :: year, month, day, hour, minute, second
1195 integer,
intent(out) :: tick
1196 integer :: iday, isec
1199 integer :: ncenturies
1201 integer :: yearx, monthx, dayx, idayx
1207 if(time%seconds >= 86400)
then
1208 call error_mesg(
'get_date',.ge.
'Time%seconds 86400 in subroutine get_date_gregorian',fatal)
1215 if( iday.eq.0 )
then
1218 else if( iday.gt.365 )
then
1219 yearx = int(iday/365) - 1
1220 ncenturies = int(yearx/100)
1221 nlpyrs = int((yearx-ncenturies*100)/4)
1222 idayx = ncenturies*36524 + (yearx-ncenturies*100)*365 + nlpyrs
1223 if( ncenturies.eq.4 ) idayx = idayx + 1
1224 l = 0 ;
if ( leap_year_gregorian_int(yearx+1) ) l = 1
1225 if ( (iday-idayx).gt.365+l )
then
1227 idayx = idayx + 365 + l
1234 l = 0 ;
if( leap_year_gregorian_int(year) ) l = 1
1236 if( dayx.le.31 )
then
1240 monthx = int(dayx/30)
1243 dayx = dayx - days_per_month(i)
1244 if(i.eq.2) dayx = dayx - l
1248 dayx = dayx - days_per_month(i)
1253 if( dayx.le.0 )
then
1255 day = dayx + days_per_month(monthx)
1256 if(monthx.eq.2) day = day + l
1260 hour = time%seconds / 3600
1261 isec = time%seconds - 3600*hour
1263 second = isec - 60*minute
1269 function cut0(string)
1270 character(len=256) :: cut0
1271 character(len=*),
intent(in) :: string
1277 if(ichar(string(i:i)) == 0 )
then
1292 integer,
intent(out) :: second, minute, hour, day, month, year
1293 integer,
intent(out) :: tick
1294 integer :: m, t, nfour, nex, days_this_month
1298 nfour = time%days / (4 * 365 + 1)
1299 day = modulo(time%days, (4 * 365 + 1))
1307 day=modulo(day, 365) + 1
1313 year = 1 + 4 * nfour + nex
1318 days_this_month = days_per_month(m)
1319 if(leap .and. m == 2) days_this_month = 29
1320 if(day <= days_this_month)
exit
1321 day = day - days_this_month
1326 hour = t / (60 * 60)
1327 t = t - hour * (60 * 60)
1329 second = t - 60 * minute
1334 subroutine get_date_julian(time, year, month, day, hour, minute, second)
1340 integer,
intent(out) :: second, minute, hour, day, month, year
1345 end subroutine get_date_julian
1355 integer,
intent(out) :: second, minute, hour, day, month, year
1356 integer,
intent(out) :: tick
1357 integer :: t, dmonth, dyear
1360 dyear = t / (30 * 12)
1362 t = t - dyear * (30 * 12)
1365 day = t -dmonth * 30 + 1
1368 hour = t / (60 * 60)
1369 t = t - hour * (60 * 60)
1371 second = t - 60 * minute
1377 subroutine get_date_no_leap_private(time, year, month, day, hour, minute, second, tick)
1382 integer,
intent(out) :: second, minute, hour, day, month, year
1383 integer,
intent(out) :: tick
1387 year = time%days / 365 + 1
1388 day = modulo(time%days, 365) + 1
1393 if(day <= days_per_month(m))
exit
1394 day = day - days_per_month(m)
1399 hour = t / (60 * 60)
1400 t = t - hour * (60 * 60)
1402 second = t - 60 * minute
1405 end subroutine get_date_no_leap_private
1408 subroutine get_date_no_leap(time, year, month, day, hour, minute, second)
1414 integer,
intent(out) :: second, minute, hour, day, month, year
1417 call get_date_no_leap_private(time, year, month, day, hour, minute, second, tick)
1419 end subroutine get_date_no_leap
1435 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1437 character(len=*),
intent(out) :: err_msg
1443 select case(calendar_type)
1444 case(thirty_day_months)
1445 set_date_private = set_date_thirty(year, month, day, hour, minute, second, tick, time_out, err_msg)
1449 set_date_private = set_date_julian_private(year, month, day, hour, minute, second, tick, time_out, err_msg)
1451 set_date_private = set_date_no_leap_private(year, month, day, hour, minute, second, tick, time_out, err_msg)
1453 err_msg =
'Cannot produce a date when calendar type is NO_CALENDAR'
1456 err_msg =
'Invalid calendar type'
1465 function set_date_i(year, month, day, hour, minute, second, tick, err_msg)
1467 integer,
intent(in) :: day, month, year
1468 integer,
intent(in),
optional :: second, minute, hour, tick
1469 character(len=*),
intent(out),
optional :: err_msg
1470 integer :: osecond, ominute, ohour, otick
1471 character(len=128) :: err_msg_local
1474 if(
present(err_msg)) err_msg =
''
1477 osecond = 0;
if(
present(second)) osecond = second
1478 ominute = 0;
if(
present(minute)) ominute = minute
1479 ohour = 0;
if(
present(hour)) ohour = hour
1480 otick = 0;
if(
present(tick)) otick = tick
1483 if(error_handler(
'function set_date_i', err_msg_local, err_msg))
return
1508 function set_date_c(string, zero_year_warning, err_msg, allow_rounding)
1510 character(len=*),
intent(in) :: string
1511 logical,
intent(in),
optional :: zero_year_warning
1512 character(len=*),
intent(out),
optional :: err_msg
1513 logical,
intent(in),
optional :: allow_rounding
1514 character(len=4) :: formt=
'(i )'
1515 logical :: correct_form, zero_year_warning_local, allow_rounding_local
1516 integer :: i1, i2, i3, i4, i5, i6, i7
1517 character(len=32) :: string_sifted_left
1518 integer :: year, month, day, hour, minute, second, tick
1519 character(len=128) :: err_msg_local
1522 if(
present(err_msg)) err_msg =
''
1523 if(
present(zero_year_warning))
then
1524 zero_year_warning_local = zero_year_warning
1526 zero_year_warning_local = .true.
1528 if(
present(allow_rounding))
then
1529 allow_rounding_local = allow_rounding
1531 allow_rounding_local = .true.
1534 string_sifted_left = adjustl(string)
1535 i1 = index(string_sifted_left,
'-')
1536 i2 = index(string_sifted_left,
'-',back=.true.)
1537 i3 = index(string_sifted_left,
':')
1538 i4 = index(string_sifted_left,
':',back=.true.)
1539 i5 = len_trim(cut0(string_sifted_left))
1540 i6 = index(string_sifted_left,
'.',back=.true.)
1541 correct_form = (i1 > 1)
1542 correct_form = correct_form .and. (i2-i1 == 2 .or. i2-i1 == 3)
1543 if(.not.correct_form)
then
1544 err_msg_local =
'Form of character time stamp is incorrect. The character time stamp is: '//trim(string)
1545 if(error_handler(
'function set_date_c', err_msg_local, err_msg))
return
1547 write(formt(3:3),
'(i1)') i1-1
1548 read(string_sifted_left(1:i1-1),formt) year
1551 if(zero_year_warning_local)
then
1552 call error_mesg(
'set_date_c',
'Year zero is invalid. Resetting year to 1', warning)
1555 write(formt(3:3),
'(i1)') i2-i1-1
1556 read(string_sifted_left(i1+1:i2-1),formt) month
1558 read(string_sifted_left(i2+1:i7),
'(i2)') day
1570 read(string_sifted_left(i5-1:i5),
'(i2)') hour
1572 else if(i3 == i4)
then
1574 read(string_sifted_left(i3-2:i3-1),
'(i2)') hour
1575 write(formt(3:3),
'(i1)') i5-i3
1576 read(string_sifted_left(i3+1:i5),formt) minute
1581 read(string_sifted_left(i3-2:i3-1),
'(i2)') hour
1582 write(formt(3:3),
'(i1)') i4-i3-1
1583 read(string_sifted_left(i3+1:i4-1),formt) minute
1584 write(formt(3:3),
'(i1)') i5-i4
1587 read(string_sifted_left(i4+1:i5),formt) second
1590 read(string_sifted_left(i4+1:i6-1),formt) second
1591 if(.not.get_tick_from_string(string_sifted_left(i6:i5), err_msg_local, allow_rounding_local, tick))
then
1592 if(error_handler(
'function set_date_c', err_msg_local, err_msg))
return
1595 if(tick == ticks_per_second)
then
1603 if(error_handler(
'function set_date_c', err_msg_local, err_msg))
return
1617 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1618 type(
time_type),
intent(out) :: time_out
1619 character(len=*),
intent(out) :: err_msg
1620 integer :: yearx, monthx, dayx, hrx, minx, secx, tickx, ncenturies, nlpyrs, l
1622 if( .not.valid_increments(year,month,day,hour,minute,second,tick,err_msg) )
then
1627 l = 0 ;
if( leap_year_gregorian_int(year) ) l = 1
1631 if(day.gt.days_per_month(month)+l .or. day.lt.1)
then
1632 err_msg =
'Invalid_date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1637 if(day.gt.days_per_month(month) .or. day.lt.1)
then
1638 err_msg =
'Invalid_date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1644 time_out%seconds = second + 60*(minute + 60*hour)
1646 yearx = mod(year-1,400)
1649 ncenturies = int( yearx/100 )
1650 nlpyrs = int( (yearx-ncenturies*100)/4 )
1651 dayx = ncenturies*36524 + (yearx-ncenturies*100)*365 + nlpyrs
1653 if(ncenturies.eq.4) dayx = dayx + 1
1656 select case( month )
1657 case(1) ; dayx = dayx
1658 case(2) ; dayx = dayx + 31
1659 case(3) ; dayx = dayx + 59 + l
1660 case(4) ; dayx = dayx + 90 + l
1661 case(5) ; dayx = dayx + 120 + l
1662 case(6) ; dayx = dayx + 151 + l
1663 case(7) ; dayx = dayx + 181 + l
1664 case(8) ; dayx = dayx + 212 + l
1665 case(9) ; dayx = dayx + 243 + l
1666 case(10) ; dayx = dayx + 273 + l
1667 case(11) ; dayx = dayx + 304 + l
1668 case(12) ; dayx = dayx + 334 + l
1672 time_out%days = dayx
1673 time_out%ticks = tick
1679 yearx = year ; monthx = month ; dayx = day
1680 hrx = hour ; minx = minute ; secx = second ; tickx = tick
1682 l = 0 ;
if( leap_year_gregorian_int(yearx) ) l = 1
1683 if( monthx.lt.1 .or. monthx.gt.12 )
then
1684 err_msg =
'Invalid_date. Date='//convert_integer_date_to_char(yearx,monthx,dayx,hour,minute,second)
1686 else if( dayx.lt.1 .or. dayx.gt.days_per_month(monthx) )
then
1687 if( monthx.eq.2 .and. dayx.le.days_per_month(monthx)+l )
return
1688 err_msg =
'Invalid_date. Date='//convert_integer_date_to_char(yearx,monthx,dayx,hour,minute,second)
1696 function set_date_julian_private(year, month, day, hour, minute, second, tick, Time_out, err_msg)
1697 logical :: set_date_julian_private
1701 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1702 type(
time_type),
intent(out) :: time_out
1703 character(len=*),
intent(out) :: err_msg
1704 integer :: ndays, m, nleapyr
1707 if( .not.valid_increments(year,month,day,hour,minute,second,tick,err_msg) )
then
1708 set_date_julian_private = .false.
1712 if(month /= 2 .and. day > days_per_month(month))
then
1713 err_msg =
'Invalid date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1714 set_date_julian_private = .false.
1719 leap = (modulo(year,4) == 0)
1721 nleapyr = (year - 1) / 4
1724 if(month == 2 .and. (day > 29 .or. ((.not. leap) .and. day > 28)))
then
1725 err_msg =
'Invalid date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1726 set_date_julian_private = .false.
1732 ndays = ndays + days_per_month(m)
1733 if(leap .and. m == 2) ndays = ndays + 1
1736 time_out%seconds = second + 60 * (minute + 60 * hour)
1737 time_out%days = day -1 + ndays + 365*(year - nleapyr - 1) + 366*(nleapyr)
1738 time_out%ticks = tick
1740 set_date_julian_private = .true.
1742 end function set_date_julian_private
1745 function set_date_julian(year, month, day, hour, minute, second)
1751 integer,
intent(in) :: year, month, day, hour, minute, second
1752 character(len=128) :: err_msg
1754 if(.not.set_date_julian_private(year, month, day, hour, minute, second, 0, set_date_julian, err_msg))
then
1755 call error_mesg(
'set_date_julian',trim(err_msg),fatal)
1758 end function set_date_julian
1761 function set_date_thirty(year, month, day, hour, minute, second, tick, Time_out, err_msg)
1762 logical :: set_date_thirty
1766 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1767 type(
time_type),
intent(out) :: time_out
1768 character(len=*),
intent(out) :: err_msg
1770 if( .not.valid_increments(year,month,day,hour,minute,second,tick,err_msg) )
then
1771 set_date_thirty = .false.
1776 err_msg =
'Invalid date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1777 set_date_thirty = .false.
1781 time_out%days = (day - 1) + 30 * ((month - 1) + 12 * (year - 1))
1782 time_out%seconds = second + 60 * (minute + 60 * hour)
1783 time_out%ticks = tick
1785 set_date_thirty = .true.
1787 end function set_date_thirty
1791 function set_date_no_leap_private(year, month, day, hour, minute, second, tick, Time_out, err_msg)
1792 logical :: set_date_no_leap_private
1796 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1797 type(
time_type),
intent(out) :: time_out
1798 character(len=*),
intent(out) :: err_msg
1801 if( .not.valid_increments(year,month,day,hour,minute,second,tick,err_msg) )
then
1802 set_date_no_leap_private = .false.
1806 if(day > days_per_month(month))
then
1807 err_msg =
'Invalid date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1808 set_date_no_leap_private = .false.
1814 ndays = ndays + days_per_month(m)
1818 time_out =
set_time(second + 60 * (minute + 60 * hour), day -1 + ndays + 365 * (year - 1), tick)
1820 set_date_no_leap_private = .true.
1822 end function set_date_no_leap_private
1825 function set_date_no_leap(year, month, day, hour, minute, second)
1831 integer,
intent(in) :: year, month, day, hour, minute, second
1832 character(len=128) :: err_msg
1834 if(.not.set_date_no_leap_private(year, month, day, hour, minute, second, 0, set_date_no_leap, err_msg))
then
1835 call error_mesg(
'set_date_no_leap',trim(err_msg),fatal)
1838 end function set_date_no_leap
1842 function valid_increments(year, month, day, hour, minute, second, tick, err_msg)
1843 logical :: valid_increments
1844 integer,
intent(in) :: year, month, day, hour, minute, second, tick
1845 character(len=128),
intent(out) :: err_msg
1850 valid_increments = .true.
1851 if(second > 59 .or. second < 0 .or. minute > 59 .or. minute < 0 &
1852 .or. hour > 23 .or. hour < 0 .or. day > 31 .or. day < 1 &
1853 .or. month > 12 .or. month < 1 .or. year < 1)
then
1854 err_msg =
'Invalid date. Date='//convert_integer_date_to_char(year,month,day,hour,minute,second)
1855 valid_increments = .false.
1858 if(tick < 0 .or. tick >= ticks_per_second)
then
1859 write(err_msg,
'(a,i6)')
'Invalid number of ticks. tick=',tick
1860 valid_increments = .false.
1863 end function valid_increments
1867 function convert_integer_date_to_char(year, month, day, hour, minute, second)
1868 character(len=19) :: convert_integer_date_to_char
1869 integer,
intent(in) :: year, month, day
1870 integer,
intent(in) :: hour, minute, second
1872 write(convert_integer_date_to_char,10) year,month,day,hour,minute,second
1873 10
format(i4.4,
'-', i2.2,
'-', i2.2,
' ', i2.2,
':', i2.2,
':', i2.2)
1875 end function convert_integer_date_to_char
1928 function increment_date(Time, years, months, days, hours, minutes, seconds, ticks, err_msg, allow_neg_inc)
1942 integer,
intent(in),
optional :: years, months, days, hours, minutes, seconds, ticks
1943 character(len=*),
intent(out),
optional :: err_msg
1944 logical,
intent(in),
optional :: allow_neg_inc
1946 integer :: oyears, omonths, odays, ohours, ominutes, oseconds, oticks
1947 character(len=128) :: err_msg_local
1948 logical :: allow_neg_inc_local
1951 if(
present(err_msg)) err_msg =
''
1954 oseconds = 0;
if(
present(seconds)) oseconds = seconds
1955 ominutes = 0;
if(
present(minutes)) ominutes = minutes
1956 ohours = 0;
if(
present(hours)) ohours = hours
1957 odays = 0;
if(
present(days)) odays = days
1958 omonths = 0;
if(
present(months)) omonths = months
1959 oyears = 0;
if(
present(years)) oyears = years
1960 oticks = 0;
if(
present(ticks)) oticks = ticks
1961 allow_neg_inc_local=.true.;
if(
present(allow_neg_inc)) allow_neg_inc_local=allow_neg_inc
1963 if(.not.allow_neg_inc_local)
then
1964 if(oyears < 0 .or. omonths < 0 .or. odays < 0 .or. ohours < 0 .or. ominutes < 0 .or. oseconds < 0 .or. &
1966 write(err_msg_local,10) oyears, omonths, odays, ohours, ominutes, oseconds, oticks
1967 if(error_handler(
'function increment_time', err_msg_local, err_msg))
return
1970 10
format(
'One or more time increments are negative: '// &
1971 'years=',i6,
' months=',i6,
' days=',i6,
' hours=',i6,
' minutes=',i6,
' seconds=',i6,
' ticks=',i6)
1974 time, oyears, omonths, odays, ohours, ominutes, oseconds, oticks, increment_date, err_msg_local))
then
1975 if(error_handler(
'function increment_date', err_msg_local, err_msg))
return
1978 end function increment_date
1998 integer,
intent(in) :: years, months, days, hours, minutes, seconds, ticks
1999 type(
time_type),
intent(out) :: time_out
2000 character(len=*),
intent(out) :: err_msg
2001 integer :: cyear , cmonth , cday , chour , cminute , csecond , ctick
2002 logical :: mode_1, mode_2
2007 mode_1 = days /= 0 .or. hours /= 0 .or. minutes /= 0 .or. seconds /= 0 .or. ticks /= 0
2008 mode_2 = years /= 0 .or. months /= 0
2010 if(.not.mode_1 .and. .not.mode_2)
then
2016 if(mode_1 .and. mode_2)
then
2017 err_msg =
'years and/or months must not be incremented with other time units'
2023 csecond = seconds + 60 * (minutes + 60 * hours)
2029 select case(calendar_type)
2030 case(thirty_day_months)
2031 call get_date_thirty (time, cyear, cmonth, cday, chour, cminute, csecond, ctick)
2033 call get_date_no_leap_private (time, cyear, cmonth, cday, chour, cminute, csecond, ctick)
2039 err_msg =
'Cannot increment a date when the calendar type is NO_CALENDAR'
2043 err_msg =
'Invalid calendar type'
2049 cmonth = cmonth + months
2052 cyear = cyear + floor(real(cmonth-1,r8_kind)/12.0_r8_kind)
2053 cmonth = modulo((cmonth-1),12) + 1
2056 cyear = cyear + years
2059 select case(calendar_type)
2060 case(thirty_day_months)
2061 increment_date_private = set_date_thirty(cyear, cmonth, cday, chour, cminute, csecond, ctick, time_out, err_msg)
2064 & time_out, err_msg)
2067 & time_out, err_msg)
2089 function decrement_date(Time, years, months, days, hours, minutes, seconds, ticks, err_msg, allow_neg_inc)
2093 integer,
intent(in),
optional :: seconds, minutes, hours, days, months, years, ticks
2096 character(len=*),
intent(out),
optional :: err_msg
2097 logical,
intent(in),
optional :: allow_neg_inc
2099 integer :: oseconds, ominutes, ohours, odays, omonths, oyears, oticks
2100 character(len=128) :: err_msg_local
2101 logical :: allow_neg_inc_local
2103 if(
present(err_msg)) err_msg =
''
2106 oseconds = 0;
if(
present(seconds)) oseconds = seconds
2107 ominutes = 0;
if(
present(minutes)) ominutes = minutes
2108 ohours = 0;
if(
present(hours)) ohours = hours
2109 odays = 0;
if(
present(days)) odays = days
2110 omonths = 0;
if(
present(months)) omonths = months
2111 oyears = 0;
if(
present(years)) oyears = years
2112 oticks = 0;
if(
present(ticks)) oticks = ticks
2113 allow_neg_inc_local=.true.;
if(
present(allow_neg_inc)) allow_neg_inc_local=allow_neg_inc
2115 if(.not.allow_neg_inc_local)
then
2116 if(oyears < 0 .or. omonths < 0 .or. odays < 0 .or. ohours < 0 .or. ominutes < 0 .or. oseconds < 0 .or. &
2118 write(err_msg_local,10) oyears, omonths, odays, ohours, ominutes, oseconds, oticks
2119 if(error_handler(
'function decrement_date', err_msg_local, err_msg))
return
2122 10
format(
'One or more time increments are negative: '// &
2123 'years=',i6,
' months=',i6,
' days=',i6,
' hours=',i6,
' minutes=',i6,
' seconds=',i6,
' ticks=',i6)
2126 time, -oyears, -omonths, -odays, -ohours, -ominutes, -oseconds, -oticks,
decrement_date, err_msg_local))
then
2127 if(error_handler(
'function decrement_date', err_msg_local, err_msg))
return
2139 character(len=*),
intent(out),
optional :: err_msg
2142 if(
present(err_msg)) err_msg =
''
2144 select case(calendar_type)
2145 case(thirty_day_months)
2154 if(error_handler(
'function days_in_month', &
2155 'days_in_month makes no sense when the calendar type is NO_CALENDAR', err_msg))
return
2157 if(error_handler(
'function days_in_month',
'Invalid calendar type', err_msg))
return
2167 integer :: year, month, day, hour, minute, second, ticks
2181 integer :: year, month, day, hour, minute, second, ticks
2207 integer :: year, month, day, hour, minute, second, ticks
2209 call get_date_no_leap_private(time, year, month, day, hour, minute, second, ticks)
2219 character(len=*),
intent(out),
optional :: err_msg
2222 if(
present(err_msg)) err_msg=
''
2224 select case(calendar_type)
2225 case(thirty_day_months)
2234 if(error_handler(
'function leap_year',
'Invalid calendar type in leap_year', err_msg))
return
2240 function leap_year_gregorian(Time)
2244 logical :: leap_year_gregorian
2246 integer :: seconds, minutes, hours, day, month, year
2248 call get_date(time, year, month, day, hours, minutes, seconds)
2249 leap_year_gregorian = leap_year_gregorian_int(year)
2251 end function leap_year_gregorian
2255 function leap_year_gregorian_int(year)
2256 logical :: leap_year_gregorian_int
2257 integer,
intent(in) :: year
2259 leap_year_gregorian_int = mod(year,4) == 0
2260 leap_year_gregorian_int = leap_year_gregorian_int .and. .not.mod(year,100) == 0
2261 leap_year_gregorian_int = leap_year_gregorian_int .or. mod(year,400) == 0
2263 end function leap_year_gregorian_int
2271 integer :: seconds, minutes, hours, day, month, year
2273 call get_date(time, year, month, day, hours, minutes, seconds)
2311 select case(calendar_type)
2312 case(thirty_day_months)
2321 call error_mesg(
'length_of_year',
'Invalid calendar type in length_of_year',fatal)
2327 function length_of_year_thirty()
2329 type(
time_type) :: length_of_year_thirty
2331 length_of_year_thirty =
set_time(0, 360)
2333 end function length_of_year_thirty
2337 function length_of_year_gregorian()
2339 type(
time_type) :: length_of_year_gregorian
2341 length_of_year_gregorian =
set_time(20952, 365)
2343 end function length_of_year_gregorian
2347 function length_of_year_julian()
2349 type(
time_type) :: length_of_year_julian
2351 length_of_year_julian =
set_time(21600, 365)
2353 end function length_of_year_julian
2357 function length_of_year_no_leap()
2359 type(
time_type) :: length_of_year_no_leap
2361 length_of_year_no_leap =
set_time(0, 365)
2363 end function length_of_year_no_leap
2372 integer :: second, minute, hour, day, month, year
2375 call get_date(time,year,month,day,hour,minute,second)
2392 select case(calendar_type)
2393 case(thirty_day_months)
2402 call error_mesg(
'days_in_year',
'Invalid calendar type in days_in_year',fatal)
2408 function days_in_year_thirty(Time)
2410 integer :: days_in_year_thirty
2413 days_in_year_thirty = 360
2415 end function days_in_year_thirty
2419 function days_in_year_gregorian(Time)
2421 integer :: days_in_year_gregorian
2424 if(leap_year_gregorian(time))
then
2425 days_in_year_gregorian = 366
2427 days_in_year_gregorian = 365
2430 end function days_in_year_gregorian
2433 function days_in_year_julian(Time)
2435 integer :: days_in_year_julian
2439 days_in_year_julian = 366
2441 days_in_year_julian = 365
2444 end function days_in_year_julian
2448 function days_in_year_no_leap(Time)
2450 integer :: days_in_year_no_leap
2453 days_in_year_no_leap = 365
2455 end function days_in_year_no_leap
2471 integer,
intent(in) :: n
2472 character (len = 9),
dimension(12) :: months = (/
'January ',
'February ', &
2473 'March ',
'April ',
'May ',
'June ',
'July ', &
2474 'August ',
'September',
'October ',
'November ',
'December '/)
2478 if(n < 1 .or. n > 12)
call error_mesg(
'month_name',
'Illegal month index',fatal)
2490 function error_handler(routine, err_msg_local, err_msg)
2493 logical :: error_handler
2494 character(len=*),
intent(in) :: routine, err_msg_local
2495 character(len=*),
intent(out),
optional :: err_msg
2497 error_handler = .false.
2498 if(
present(err_msg))
then
2499 err_msg = err_msg_local
2500 error_handler = .true.
2502 call error_mesg(trim(routine),trim(err_msg_local),fatal)
2505 end function error_handler
2512 if (module_is_initialized)
return
2515 module_is_initialized = .true.
2526 character (len=*),
intent(in),
optional :: str
2527 integer ,
intent(in),
optional :: unit
2528 integer :: s,d,ticks, ns,nd,nt, unit_in
2529 character(len=19) :: fmt
2535 if (
present(unit)) unit_in = unit
2541 nd = int(log10(real(max(1,d))))+1
2542 ns = int(log10(real(max(1,s))))+1
2543 nt = int(log10(real(max(1,ticks))))+1
2544 write (fmt,10) nd, ns, nt
2545 10
format (
'(a,i',i2.2,
',a,i',i2.2,
',a,i',i2.2,
')')
2547 if (
present(str))
then
2548 write (unit_in,fmt) trim(str)//
' day=', d,
', sec=', s,
', ticks=', ticks
2550 write (unit_in,fmt)
'TIME: day=', d,
', sec=', s,
', ticks=', ticks
2561 character (len=*),
intent(in),
optional :: str
2562 integer ,
intent(in),
optional :: unit
2563 integer :: y,mo,d,h,m,s, unit_in
2564 character(len=9) :: mon
2570 if (
present(unit)) unit_in = unit
2574 if (
present(str))
then
2575 write (unit_in,10) trim(str)//
' ', y,mon(1:3),
' ',d,
' ',h,
':',m,
':',s
2577 write (unit_in,10)
'DATE: ', y,mon(1:3),
' ',d,
' ',h,
':',m,
':',s
2579 10
format (a,i4,1x,a3,4(a1,i2.2))
2590 integer,
intent(in) :: ncal
2591 character(len=*),
intent(out),
optional :: err_msg
2593 character(len=128) :: err_msg_local
2597 if(
present(err_msg)) err_msg =
''
2599 if(ncal == no_calendar)
then
2601 else if(ncal == thirty_day_months)
then
2603 else if(ncal == julian)
then
2605 else if(ncal == gregorian)
then
2607 else if(ncal == noleap)
then
2610 write(err_msg_local,
'(a,i4,a)')
'calendar type=',ncal,
' is invalid.'
2611 if(error_handler(
'function valid_calendar_types', err_msg_local, err_msg))
return
2621 character(len=*),
intent(out),
optional :: err_msg
2622 character(len=128) :: err_msg_local
2624 integer :: yr,mon,day,hr,min,sec
2626 if(
present(err_msg)) err_msg =
''
2627 call get_date(time,yr,mon,day,hr,min,sec)
2628 if (yr <= 9999)
then
2629 write(
date_to_string,
'(I4.4,I2.2,I2.2,".",I2.2,I2.2,I2.2)') yr, mon, day, hr, min, sec
2631 write(err_msg_local,
'(a,i4.4,a)')
'year = ', yr,
' should be less than 10000'
2632 if(error_handler(
'function date_to_string', err_msg_local, err_msg))
return
2641 character(len=:),
allocatable :: terr
2643 allocate (
character(len=10) :: terr)
2645 write (terr,
'(I0)') t%days
2648 end module time_manager_mod
subroutine, public write_version_number(version, tag, unit)
Prints to the log file (or a specified unit) the version id string and tag name.
subroutine, public error_mesg(routine, message, level)
Print notes, warnings and error messages; terminates program for warning and error messages....
integer function stdout()
This function returns the current standard fortran unit numbers for output.
type(time_type) function, public length_of_year()
Returns the mean length of the year in the default calendar setting.
integer function, public get_ticks_per_second()
Returns the number of ticks per second.
integer function days_in_month_gregorian(Time)
Returns the number of days in a gregorian month.
logical function, public leap_year(Time, err_msg)
Returns true if the year corresponding to the input time is a leap year (for default calendar)....
type(time_type) function set_date_i(year, month, day, hour, minute, second, tick, err_msg)
Calls set_date_private to set days for different calendar types.
integer function, public day_of_year(time)
Returns number of day in year for given time. Jan 1st is day 1, not zero!
type(time_type) function, public decrement_time(Time, seconds, days, ticks, err_msg, allow_neg_inc)
Decrements a time by seconds and days.
type(time_type) function set_time_c(string, err_msg, allow_rounding)
Returns a time_type set to the given amount of time via a string.
type(time_type) function set_date_c(string, zero_year_warning, err_msg, allow_rounding)
Calls set_date_private for different calendar types when given a string input. Examples of acceptable...
type(time_type) function time_scalar_divide(time, n)
Returns the largest time, t, for which n * t <= time.
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
Returns days and seconds ( < 86400 ) corresponding to a time. err_msg should be checked for any error...
type(time_type) function time_scalar_mult(time, n)
Returns time multiplied by integer factor n.
logical function leap_year_thirty(Time)
No leap years in thirty day months, included for transparency.
character(len=15) function, public date_to_string(time, err_msg)
Get the a character string that represents the time. The format will be yyyymmdd.hhmmss.
subroutine, public set_ticks_per_second(tps)
Sets the number of ticks per second.
character(len=24) function, public valid_calendar_types(ncal, err_msg)
Returns a character string that describes the calendar type corresponding to the input integer.
type(time_type) function, public decrement_date(Time, years, months, days, hours, minutes, seconds, ticks, err_msg, allow_neg_inc)
Given a time and some date decrement, computes a new time. Depending on the mapping algorithm from da...
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
Gets the date for different calendar types. Given a time_interval, returns the corresponding date und...
integer function, public days_in_year(Time)
Returns the number of days in the calendar year corresponding to the date represented by time for the...
type(time_type) function scalar_time_mult(n, time)
Returns time multipled by integer factor n.
type(time_type) function, public increment_time(Time, seconds, days, ticks, err_msg, allow_neg_inc)
Increments a time by seconds and days.
logical function leap_year_julian(Time)
Returns the number of days in a julian month.
subroutine, public print_date(Time, str, unit)
Prints the time to standard output (or optional unit) as a date.
subroutine get_date_gregorian(time, year, month, day, hour, minute, second, tick)
Gets the date on a Gregorian calendar. Computes the year, month, day on the fly from the quantity tim...
type(time_type) function set_time_i(seconds, days, ticks, err_msg)
Returns a time_type set to the given amount of time via integer amounts.
integer function days_in_month_julian(Time)
Returns the number of days in a julian month.
subroutine get_date_julian_private(time, year, month, day, hour, minute, second, tick)
Base date for Julian calendar is year 1 with all multiples of 4 years being leap years.
subroutine, public time_manager_init()
Initialization routine. Writes the version information to the log file.
logical function set_date_gregorian(year, month, day, hour, minute, second, tick, Time_out, err_msg)
Sets Time_outdays on a Gregorian calendar Computes the total number of days between 1/1/0001 to the c...
logical function set_date_private(year, month, day, hour, minute, second, tick, Time_out, err_msg)
Sets days for different calendar types. Given an input date in year, month, days, etc....
integer function days_in_month_thirty(Time)
Returns the number of days in a thirty day month (needed for transparent changes to calendar type).
subroutine get_date_thirty(time, year, month, day, hour, minute, second, tick)
Computes date corresponding to time interval for 30 day months, 12 month years.
type(time_type) function real4_to_time_type(x, err_msg)
integer function, public days_in_month(Time, err_msg)
Given a time, computes the corresponding date given the selected date time mapping algorithm.
logical function increment_time_private(Time_in, seconds, days, ticks, Time_out, err_msg)
Increments a time by seconds, days and ticks.
logical function set_time_private(seconds, days, ticks, Time_out, err_msg)
Returns a time interval corresponding to this number of days, seconds, and ticks. days,...
integer, parameter days_in_400_year_period
Used only for gregorian.
character(len=9) function, public month_name(n)
Returns a character string containing the name of the month corresponding to month number n.
type(time_type) function real8_to_time_type(x, err_msg)
Convert a real number of seconds into a time_type variable.
integer function safe_rtoi(rval, mode)
Convert a floating point value to an integer value.
real(kind=r8_kind) function, public time_type_to_real(time)
Converts time to seconds and returns it as a real number.
logical function leap_year_no_leap(Time)
Another tough one; no leap year returns false for leap year inquiry.
integer function days_in_month_no_leap(Time)
Returns the number of days in a 365 day year month.
logical function, public repeat_alarm(time, alarm_frequency, alarm_length)
Repeat_alarm supports an alarm that goes off with alarm_frequency and lasts for alarm_length....
logical function, public interval_alarm(time, time_interval, alarm, alarm_interval)
Supports a commonly used type of test on times for models. Given the current time,...
integer function time_divide(time1, time2)
Returns the largest integer, n, for which time1 >= time2 * n.
integer function, public get_calendar_type()
Returns default calendar type for mapping from time to date.
subroutine, public print_time(Time, str, unit)
Prints the given time_type argument as a time (using days, seconds and ticks)
subroutine, public set_calendar_type(type, err_msg)
Sets calendar_type for mapping an interval to a date. For the Gregorian calendar, negative years and ...
logical function increment_date_private(Time, years, months, days, hours, minutes, seconds, ticks, Time_out, err_msg)
Given a time and some date increment, computes a new time. Depending on the mapping algorithm from da...
subroutine, public time_list_error(T, Terr)
This routine converts the integer tdays to a string.
Given an input date in year, month, days, etc., creates a time_type that represents this time interva...
Given some number of seconds and days, returns the corresponding time_type.
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.
Wrapper for the real to time interface Takes seconds as reals to convert to a time_type representatio...