A software package that provides a set of simple interfaces for modelers to perform computations related to time and dates.
fms_mod
| Name | Type | Value | Units | Description |
|---|---|---|---|---|
| time_type | derived type | --- | --- | Derived-type data variable used to store time and date quantities. It contains two PRIVATE variables: seconds and days. |
set_time (seconds, days)
| seconds | A number of seconds (can be greater than 86400), must be positive. [integer, dimension(scalar)] |
| days | A number of days, must be positive. [integer, dimension(scalar)] |
| A time interval corresponding to this number of days and seconds. [, dimension] |
get_time (time, seconds, days)
| time | A time interval. [time_type] |
| seconds | A number of seconds (< 86400). [integer, dimension(scalar)] |
| days | A number of days, must be positive. [integer, dimension(scalar)] |
increment_time (time, seconds, days)
| time | A time interval. [time_type, dimension] |
| seconds | Increment of seconds (can be greater than 86400); must be positive. [integer, dimension(scalar)] |
| days | Increment of days; must be positive. [integer, dimension(scalar)] |
| A time that adds this increment to the input time. [, dimension] |
decrement_time (time, seconds, days)
| time | A time interval. [time_type, dimension] |
| seconds | Decrement of seconds (can be greater than 86400); must be positive. [integer, dimension(scalar)] |
| days | Decrement of days; must be positive. [integer, dimension(scalar)] |
| A time that subtracts this decrement from an input time. If
the result is negative, it is considered a fatal error. [, dimension] |
time_gt (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 > time2 [logical, dimension] |
time_ge (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 >= time2 [logical, dimension] |
time_lt (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 < time2 [logical, dimension] |
time_le (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 <= time2 [logical, dimension] |
time_eq (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 == time2 [logical, dimension] |
time_ne (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns true if time1 /= time2 [logical, dimension] |
time_plus (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns sum of two time_types. [time_type, dimension] |
time_minus (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns difference of two time_types. [time_type, dimension] |
time_scalar_mult (time, n)
| time | A time interval. [time_type, dimension] |
| n | A time interval. [integer, dimension] |
| Returns time multiplied by integer factor n. [time_type, dimension] |
scalar_time_mult (n, time)
| time | A time interval. [time_type, dimension] |
| n | An integer. [integer, dimension] |
| Returns time multiplied by integer factor n. [time_type, dimension] |
time_divide (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns the largest integer, n, for which time1 >= time2 * n. [integer, dimension] |
time_real_divide (time1, time2)
| time1 | A time interval. [time_type, dimension] |
| time2 | A time interval. [time_type, dimension] |
| Returns the double precision quotient of two times [integer, dimensiondouble precision] |
time_type_to_real (time)
| time | A time interval. [time_type, dimension] |
real_to_time_type (x)
| x | A real number of seconds [real, dimension] |
time_scalar_divide (time, n)
| time | A time interval. [time_type, dimension] |
| n | An integer factor. [integer, dimension] |
| Returns the largest time, t, for which n * t <= time. [integer, dimensiondouble precision] |
interval_alarm (time, time_interval, alarm, alarm_interval)
| time | Current time. [time_type] |
| time_interval | A time interval. [time_type] |
| alarm_interval | A time interval. [time_type] |
| alarm | An alarm time, which is incremented by the alarm_interval
if the function is true. [time_type] |
| interval_alarm | Returns either True or false. [logical] |
repeat_alarm (time, alarm_frequency, alarm_length)
| time | Current time. [time_type] |
| alarm_frequency | A time interval for alarm_frequency. [time_type] |
| alarm_length | A time interval for alarm_length. [time_type] |
| repeat_alarm | Returns either True or false. [logical] |
set_calendar_type (type)
| type | A constant number for setting the calendar type. [integer, dimension] |
| calendar_type | A constant number for default calendar type. [integer] |
get_calendar_type ()
get_date (time, year, month, day, hour, minute, second)
| time | A time interval. [time_type] |
| day |
[integer] |
| month |
[integer] |
| year |
[integer] |
| second |
[integer] |
| minute |
[integer] |
| hour |
[integer] |
get_cal_time (time_increment, units, calendar)
| time_increment | A time interval. [real] |
| units | Examples of acceptable values of units:
'days since 1980-01-01 00:00:00', 'hours since 1980-1-1 0:0:0', 'minutes since 0001-4-12' The first word in the string must be 'years', 'months', 'days', 'hours', 'minutes' or 'seconds'. The second word must be 'since' year number must occupy 4 spaces. Number of months, days, hours, minutes, seconds may occupy 1 or 2 spaces year, month and day must be separated by a '-' hour, minute, second must be separated by a ':' hour, minute, second are optional. If not present then zero is assumed. Because months are not equal increments of time, and, for julian calendar, neither are years, the 'years since' and 'month since' cases deserve further explaination. When 'years since' is used: The year number is increased by floor(time_increment) to obtain a time T1. The year number is increased by floor(time_increment)+1 to obtain a time T2. The time returned is T1 + (time_increment-floor(time_increment))*(T2-T1). When 'months since' is used: The month number is increased by floor(time_increment). If it falls outside to range 1 to 12 then it is adjusted along with the year number to convert to a valid date. The number of days in the month of this date is used to compute the time interval of the fraction. That is: The month number is increased by floor(time_increment) to obtain a time T1. delt = the number of days in the month in which T1 falls. The time returned is T1 + ((time_increment-floor(time_increment))*delt. Two of the consequences of this scheme should be kept in mind. -- The time since should not be from the 29'th to 31'st of a month, since an invalid date is likely to result, triggering an error stop. -- When time since is from the begining of a month, the fraction of a month will never advance into the month after that which results from only the whole number. When NO_CALENDAR is in effect, units attribute must specify a starting day and second, with day number appearing first Example: 'days since 100 0' Indicates 100 days 0 seconds [character] |
| calendar | When present, then it will be checked against the calendar in use
by the time manager. If it does not match the calendar in use then
the program will terminate with an error message.
When not present, no such check is done.
Acceptable values of calendar are: noleap 365_day 360_day julian thirty_day_months no_calendar [character] |
set_date (year, month, day, hours, minutes, seconds)
| time | A time interval. [time_type] |
| day |
[integer] |
| month |
[integer] |
| year |
[integer] |
| second |
[integer] |
| minute |
[integer] |
| hour |
[integer] |
| set_date | A time interval. [time_type] |
increment_date (time, years, months, days, hours, minutes, seconds)
| time | A time interval. [time_type] |
| day | An increment of days. [integer] |
| month | An increment of months. [integer] |
| year | An increment of years. [integer] |
| second | An increment of seconds. [integer] |
| minute | An increment of minutes. [integer] |
| hour | An increment of hours. [integer] |
| increment_date | A new time based on the input
time interval and the default calendar type. [time_type] |
decrement_date (time, years, months, days, hours, minutes, seconds)
| time | A time interval. [time_type] |
| day | A decrement of days. [integer] |
| month | A deincrement of months. [integer] |
| year | A deincrement of years. [integer] |
| second | A deincrement of seconds. [integer] |
| minute | A deincrement of minutes. [integer] |
| hour | A deincrement of hours. [integer] |
| decrement_date | A new time based on the input
time interval and the default calendar type. [time_type] |
days_in_month (time)
| time | A time interval. [time_type, dimension] |
| days_in_month | The number of days in the month given the selected time
mapping algorithm. [integer, dimension] |
leap_year (time)
| time | A time interval. [time_type, dimension] |
| leap_year | True if the year corresponding to the date for the default
calendar is a leap year. False for THIRTY_DAY_MONTHS and
NOLEAP and otherwise. [calendar_type, dimension] |
length_of_year ()
days_in_year ()
| time | A time interval. [time_type] |
| The number of days in this year for the default calendar type. |
month_name (n)
| n | Month number. [integer] |
| month_name | The character string associated with a month. For now all
calendars have 12 months and will return standard names. [character] |
time_manager_init ()
print_time (time,str,unit)
| time | Time that will be printed. [time_type] |
| str | Character string that precedes the printed time or date. [character (len=*)] |
| unit | Unit number for printed output. The default unit is stdout. [integer] |
print_date (time,str,unit)
| time | Time that will be printed. [time_type] |
| str | Character string that precedes the printed time or date. [character (len=*)] |
| unit | Unit number for printed output. The default unit is stdout. [integer] |
use time_manager_mod
implicit none
type(time_type) :: dt, init_date, astro_base_date, time, final_date
type(time_type) :: next_rad_time, mid_date
type(time_type) :: repeat_alarm_freq, repeat_alarm_length
integer :: num_steps, i, days, months, years, seconds, minutes, hours
integer :: months2, length
real :: astro_days
Set calendar type
call set_calendar_type(THIRTY_DAY_MONTHS)
call set_calendar_type(JULIAN)
call set_calendar_type(NOLEAP)
Set timestep
dt = set_time(1100, 0)
Set initial date
init_date = set_date(1992, 1, 1)
Set date for astronomy delta calculation
astro_base_date = set_date(1970, 1, 1, 12, 0, 0)
Copy initial time to model current time
time = init_date
Determine how many steps to do to run one year
final_date = increment_date(init_date, years = 1)
num_steps = (final_date - init_date) / dt
write(*, *) 'Number of steps is' , num_steps
Want to compute radiation at initial step, then every two hours
next_rad_time = time + set_time(7200, 0)
Test repeat alarm
repeat_alarm_freq = set_time(0, 1)
repeat_alarm_length = set_time(7200, 0)
Loop through a year
do i = 1, num_steps
Increment time
time = time + dt
Test repeat alarm
if(repeat_alarm(time, repeat_alarm_freq, repeat_alarm_length)) &
write(*, *) 'REPEAT ALARM IS TRUE'
Should radiation be computed? Three possible tests.
First test assumes exact interval; just ask if times are equal
if(time == next_rad_time) then
Second test computes rad on last time step that is <= radiation time
if((next_rad_time - time) < dt .and. time < next_rad) then
Third test computes rad on time step closest to radiation time
if(interval_alarm(time, dt, next_rad_time, set_time(7200, 0))) then
call get_date(time, years, months, days, hours, minutes, seconds)
write(*, *) days, month_name(months), years, hours, minutes, seconds
Need to compute real number of days between current time and astro_base
call get_time(time - astro_base_date, seconds, days)
astro_days = days + seconds / 86400.
write(*, *) 'astro offset ', astro_days
end if
Can compute daily, monthly, yearly, hourly, etc. diagnostics as for rad
Example: do diagnostics on last time step of this month
call get_date(time + dt, years, months2, days, hours, minutes, seconds)
call get_date(time, years, months, days, hours, minutes, seconds)
if(months /= months2) then
write(*, *) 'last timestep of month'
write(*, *) days, months, years, hours, minutes, seconds
endif
Example: mid-month diagnostics; inefficient to make things clear
length = days_in_month(time)
call get_date(time, years, months, days, hours, minutes, seconds)
mid_date = set_date(years, months, 1) + set_time(0, length) / 2
if(time < mid_date .and. (mid_date - time) < dt) then
write(*, *) 'mid-month time'
write(*, *) days, months, years, hours, minutes, seconds
endif
end do end program time_main2