61 #include<file_version.h> 167 function get_cal_time(time_increment, units, calendar, permit_calendar_conversion)
168 real,
intent(in) :: time_increment
169 character(len=*),
intent(in) :: units
170 character(len=*),
intent(in) :: calendar
171 logical,
intent(in),
optional :: permit_calendar_conversion
173 integer :: year, month, day, hour, minute, second
174 integer :: i1, i2, i3, i4, i5, i6, increment_seconds, increment_days, increment_years, increment_months
175 real :: month_fraction
176 integer :: calendar_tm_i, calendar_in_i, namelist_unit, ierr, io, logunit
177 logical :: correct_form
178 character(len=32) :: calendar_in_c
179 character(len=64) :: err_msg
180 character(len=4) :: formt=
'(i )' 181 type(
time_type) :: base_time, base_time_plus_one_yr, base_time_plus_one_mo
183 logical :: permit_conversion_local
186 #ifdef INTERNAL_FILE_NML 190 namelist_unit = open_namelist_file()
193 read(namelist_unit, nml=get_cal_time_nml, iostat=io, end=20)
196 20
call close_file (namelist_unit)
199 call write_version_number(
"GET_CAL_TIME_MOD", version)
201 if(mpp_pe() == mpp_root_pe())
write (logunit, nml=get_cal_time_nml)
205 if(
present(permit_calendar_conversion))
then 206 permit_conversion_local = permit_calendar_conversion
211 calendar_in_c = lowercase(trim(
cut0(calendar)))
213 correct_form = (trim(calendar_in_c)) ==
'noleap' .or. (trim(calendar_in_c)) ==
'365_day' .or. &
214 (trim(calendar_in_c)) ==
'360_day' .or. (trim(calendar_in_c)) ==
'julian' .or. &
215 (trim(calendar_in_c)) ==
'no_calendar'.or. (trim(calendar_in_c)) ==
'thirty_day_months' .or. &
216 (trim(calendar_in_c)) ==
'gregorian' 218 if(.not.correct_form)
then 219 call error_mesg(
'get_cal_time',
'"'//trim(calendar_in_c)//
'"'// &
220 ' is not an acceptable calendar attribute. acceptable calendars are: '// &
221 ' noleap, 365_day, 360_day, julian, no_calendar, thirty_day_months, gregorian',fatal)
226 if(.not.permit_conversion_local)
then 227 correct_form = (trim(calendar_in_c) ==
'noleap' .and. calendar_tm_i ==
noleap) .or. &
228 (trim(calendar_in_c) ==
'365_day' .and. calendar_tm_i ==
noleap) .or. &
229 (trim(calendar_in_c) ==
'360_day' .and. calendar_tm_i ==
thirty_day_months) .or. &
230 (trim(calendar_in_c) ==
'thirty_day_months' .and. calendar_tm_i ==
thirty_day_months) .or. &
231 (trim(calendar_in_c) ==
'julian' .and. calendar_tm_i ==
julian) .or. &
232 (trim(calendar_in_c) ==
'no_calendar' .and. calendar_tm_i ==
no_calendar) .or. &
233 (trim(calendar_in_c) ==
'gregorian' .and. calendar_tm_i ==
gregorian)
234 if(.not.correct_form)
then 235 call error_mesg(
'get_cal_time',
'calendar not consistent with calendar type in use by time_manager.'// &
236 ' calendar='//trim(calendar_in_c)//
'. Type in use by time_manager='//
valid_calendar_types(calendar_tm_i),fatal)
240 if (permit_conversion_local)
then 241 select case (trim(calendar_in_c))
248 case (
'thirty_day_months')
258 trim(calendar_in_c)//
' is an invalid calendar type (specified in call to get_cal_time)',fatal)
261 calendar_in_i = calendar_tm_i
264 correct_form = lowercase(units(1:10)) ==
'days since' .or. &
265 lowercase(units(1:11)) ==
'hours since' .or. &
266 lowercase(units(1:13)) ==
'minutes since' .or. &
267 lowercase(units(1:13)) ==
'seconds since' 270 correct_form = correct_form .or. &
271 lowercase(units(1:11)) ==
'years since' .or. &
272 lowercase(units(1:12)) ==
'months since' 275 if(.not.correct_form)
then 276 call error_mesg(
'get_cal_time',trim(units)//
' is an invalid string for units.' // &
277 ' units must begin with a time unit then the word "since"' // &
278 ' Valid time units are: "seconds" "minutes", "hours", "days", and, ' // &
279 ' except when NO_CALENDAR is in effect, "months" and "years"',fatal)
282 if(calendar_in_i /= calendar_tm_i)
then 296 i1 = index(units,
'since') + 5
298 base_time =
set_time(units(i1:len_trim(units)))
300 base_time =
set_date(units(i1:len_trim(units)))
303 if(lowercase(units(1:10)) ==
'days since')
then 304 increment_days = floor(time_increment)
305 increment_seconds = 86400*(time_increment - increment_days)
306 else if(lowercase(units(1:11)) ==
'hours since')
then 307 increment_days = floor(time_increment/24)
308 increment_seconds = 86400*(time_increment/24 - increment_days)
309 else if(lowercase(units(1:13)) ==
'minutes since')
then 310 increment_days = floor(time_increment/1440)
311 increment_seconds = 86400*(time_increment/1440 - increment_days)
312 else if(lowercase(units(1:13)) ==
'seconds since')
then 313 increment_days = floor(time_increment/86400)
314 increment_seconds = 86400*(time_increment/86400 - increment_days)
315 else if(lowercase(units(1:11)) ==
'years since')
then 319 call get_date(base_time, year,month,day,hour,minute,second)
320 base_time =
set_date(year+floor(time_increment) ,month,day,hour,minute,second)
321 base_time_plus_one_yr =
set_date(year+floor(time_increment)+1,month,day,hour,minute,second)
322 call get_time(base_time_plus_one_yr - base_time, second, day)
323 dt = (day*86400+second)*(time_increment-floor(time_increment))
324 increment_days = floor(dt/86400)
325 increment_seconds = dt - increment_days*86400
326 else if(lowercase(units(1:12)) ==
'months since')
then 327 month_fraction = time_increment - floor(time_increment)
328 increment_years = floor(time_increment/12)
329 increment_months = floor(time_increment) - 12*increment_years
330 call get_date(base_time, year,month,day,hour,minute,second)
331 base_time =
set_date(year+increment_years,month+increment_months ,day,hour,minute,second)
333 increment_days = floor(dt/86400)
334 increment_seconds = dt - increment_days*86400
336 call error_mesg(
'get_cal_time',
'"'//trim(units)//
'"'//
' is not an acceptable units attribute of time.'// &
337 ' It must begin with: "years since", "months since", "days since", "hours since", "minutes since", or "seconds since"',fatal)
340 if (calendar_in_i /= calendar_tm_i)
then 342 call error_mesg(
'get_cal_time',
'Cannot do calendar conversion because input calendar is '// &
344 ' Conversion cannot be done if either is NO_CALENDAR',fatal)
346 call get_date(base_time,year, month, day, hour, minute, second)
351 if(err_msg /=
'')
then 352 call error_mesg(
'get_cal_time',
'Error in function get_cal_time: '//trim(err_msg)// &
353 ' Note that the time_manager is using the '//trim(
valid_calendar_types(calendar_tm_i))//
' calendar '// &
354 'while the calendar type passed to function get_cal_time is '//calendar_in_c,fatal)
363 function cut0(string)
365 character(len=*),
intent(in) ::
string 371 if(ichar(
string(i:i)) == 0 )
then
subroutine, public get_date(time, year, month, day, hour, minute, second, tick, err_msg)
integer, parameter, public gregorian
integer, parameter, public noleap
logical module_is_initialized
character(len=256) function cut0(string)
type(time_type) function, public get_cal_time(time_increment, units, calendar, permit_calendar_conversion)
integer function, public check_nml_error(IOSTAT, NML_NAME)
character(len=input_str_length), dimension(:), allocatable, target, public input_nml_file
subroutine, public set_calendar_type(type, err_msg)
character(len=24) function, public valid_calendar_types(ncal, err_msg)
integer function, public days_in_month(Time, err_msg)
integer, parameter, public julian
integer function, public get_calendar_type()
integer, parameter, public thirty_day_months
integer, parameter, public no_calendar
logical allow_calendar_conversion
subroutine, public get_time(Time, seconds, days, ticks, err_msg)
subroutine, public error_mesg(routine, message, level)