gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
Functions/Subroutines | Variables
dc_calendar_internal Module Reference

Internal module for dc_calendar. More...

Functions/Subroutines

subroutine, public default_cal_set
 
integer function, public dccaldate_normalize (year, month, day, hour, min, sec, cal)
 
integer function, public dccaldate_ym2d (year, month, day, cal, day_of_year)
 
character(token) function, public dccaltype_str (cal_type)
 
character(token) function, public dccaldate_str2ustr (str)
 
integer function, public dccaldate_str2usym (str)
 

Variables

type(dc_cal), target, save, public default_cal
 Default calendar object
 
type(dc_cal_date), target, save, public default_date
 Default date object
 

Detailed Description

Internal module for dc_calendar.

Author
Yasuhiro MORIKAWA

Function/Subroutine Documentation

◆ dccaldate_normalize()

integer function, public dc_calendar_internal::dccaldate_normalize ( integer, intent(inout)  year,
integer, intent(inout)  month,
integer, intent(inout)  day,
integer, intent(inout)  hour,
integer, intent(inout)  min,
real(dp), intent(inout)  sec,
type(dc_cal), intent(in)  cal 
)

Normalize date information

Normalizes date information according to calendar. This is an internal procedure for dc_calendar module.

Normalization is performed in the following cases:

  • sec exceeds "seconds in a minute": carry over to minute
  • min exceeds "minutes in an hour": carry over to hour
  • hour exceeds "hours in a day": carry over to day
  • day exceeds "days in a month": carry over to month/year
  • sec, min, hour, day are negative: borrow from upper unit
  • day is 0: borrow from upper unit
Parameters
[in,out]yearYear
[in,out]monthMonth
[in,out]dayDay
[in,out]hourHour
[in,out]minMinute
[in,out]secSecond
[in]calCalendar object
Returns
Status (DC_NOERR on success, DC_EINCONSISTCALDATE on error)

Definition at line 177 of file dc_calendar_internal.f90.

179 use dc_calendar_types, only: &
181 implicit none
182 integer:: stat
183 integer, intent(inout):: year
184 integer, intent(inout):: month
185 integer, intent(inout):: day
186 integer, intent(inout):: hour
187 integer, intent(inout):: min
188 real(DP), intent(inout):: sec
189 type(DC_CAL), intent(in):: cal
190
191 integer:: day_in_month_jg
192 integer, pointer:: day_in_month(:) =>null()
193
194 integer:: month_in_year
195 integer:: hour_in_day
196 integer:: min_in_hour
197 real(DP):: sec_in_min
198
199 real(DP):: wyear, wday, whour, wmin
200 real(DP):: wdb, ychunk_e6, ychunk_e3, chunk_scale_e6, chunk_scale_e3
201 continue
202 stat = dc_noerr
203
204 select case( cal % cal_type )
205 case( cal_user_defined )
206 if ( month > cal % month_in_year ) stat = dc_einconsistcaldate
207 case default
208 if ( month > 12 ) stat = dc_einconsistcaldate
209 end select
210
211 if ( stat /= dc_noerr ) return
212
213 month_in_year = cal % month_in_year
214 hour_in_day = cal % hour_in_day
215 min_in_hour = cal % min_in_hour
216 sec_in_min = cal % sec_in_min
217 day_in_month => cal % day_in_month
218
219 select case( cal % cal_type )
220 case( cal_julian )
221 chunk_scale_e6 = 4.0e+5
222 ychunk_e6 = 146100000.0_dp
223 chunk_scale_e3 = 4.0e+2
224 ychunk_e3 = 146100.0_dp
225 case( cal_gregorian )
226 chunk_scale_e6 = 4.0e+5
227 ychunk_e6 = 146097000.0_dp
228 chunk_scale_e3 = 4.0e+2
229 ychunk_e3 = 146097.0_dp
230 case default
231 chunk_scale_e6 = 1.0e+6
232 ychunk_e6 = chunk_scale_e6 * sum( day_in_month(:) )
233 chunk_scale_e3 = 1.0e+3
234 ychunk_e3 = chunk_scale_e3 * sum( day_in_month(:) )
235 end select
236
237 wyear = real( year, dp )
238 wday = real( day, dp )
239 whour = real( hour, dp )
240 wmin = real( min, dp )
241
242 if ( .not. sec < sec_in_min ) then
243 wmin = wmin + aint( sec / sec_in_min )
244 sec = mod( sec, sec_in_min )
245 elseif ( sec < 0.0_dp ) then
246 wdb = ceiling( abs(sec) / sec_in_min )
247 wmin = wmin - wdb
248 sec = sec + wdb * sec_in_min
249 end if
250
251 if ( .not. wmin < min_in_hour ) then
252 whour = whour + aint( wmin / min_in_hour )
253 wmin = mod( wmin, real( min_in_hour, dp ) )
254 elseif ( wmin < 0 ) then
255 wdb = ceiling( abs(wmin) / real(min_in_hour) )
256 whour = whour - wdb
257 wmin = wmin + wdb * min_in_hour
258 end if
259
260 if ( .not. whour < hour_in_day ) then
261 wday = wday + aint( whour / hour_in_day )
262 whour = mod( whour, real( hour_in_day, dp ) )
263 elseif ( whour < 0 ) then
264 wdb = ceiling( abs(whour) / real(hour_in_day) )
265 wday = wday - wdb
266 whour = whour + wdb * hour_in_day
267 end if
268
269 if ( wday < 1.0_dp ) then
270 select case( cal % cal_type )
271 case( cal_julian )
272 do while ( wday < 1.0_dp )
273 if ( wday < - ychunk_e6 ) then
274 wyear = wyear + chunk_scale_e6 * ( aint( wday / ychunk_e6 ) - 1.0_dp )
275 wday = mod( wday, ychunk_e6 ) + ychunk_e6
276 end if
277 if ( wday < 1.0_dp ) then
278 wyear = wyear + chunk_scale_e3 * ( aint( wday / ychunk_e3 ) - 1.0_dp )
279 wday = mod( wday, ychunk_e3 ) + ychunk_e3
280 end if
281 end do
282 case( cal_gregorian )
283 do while ( wday < 1.0_dp )
284 if ( wday < - ychunk_e6 ) then
285 wyear = wyear + chunk_scale_e6 * ( aint( wday / ychunk_e6 ) - 1.0_dp )
286 wday = mod( wday, ychunk_e6 ) + ychunk_e6
287 end if
288 if ( wday < 1.0_dp ) then
289 wyear = wyear + chunk_scale_e3 * ( aint( wday / ychunk_e3 ) - 1.0_dp )
290 wday = mod( wday, ychunk_e3 ) + ychunk_e3
291 end if
292 end do
293 case default
294 do while ( wday < 1.0_dp )
295 if ( wday < - ychunk_e6 ) then
296 wyear = wyear + chunk_scale_e6 * ( aint( wday / ychunk_e6 ) - 1.0_dp )
297 wday = mod( wday, ychunk_e6 ) + ychunk_e6
298 end if
299 if ( wday < 1.0_dp ) then
300 wyear = wyear + chunk_scale_e3 * ( aint( wday / ychunk_e3 ) - 1.0_dp )
301 wday = mod( wday, ychunk_e3 ) + ychunk_e3
302 end if
303 end do
304 end select
305 end if
306
307 select case( cal % cal_type )
308 case( cal_julian )
309 if ( wday > ychunk_e6 ) then
310 wyear = wyear + chunk_scale_e6 * aint( wday / ychunk_e6 )
311 wday = mod( wday, ychunk_e6 )
312 end if
313 if ( wday > ychunk_e3 ) then
314 wyear = wyear + chunk_scale_e3 * aint( wday / ychunk_e3 )
315 wday = mod( wday, ychunk_e3 )
316 end if
317 do
318 if ( month == 2 ) then
319 if ( mod( nint(wyear), 4 ) == 0 ) then
320 day_in_month_jg = 29
321 else
322 day_in_month_jg = 28
323 end if
324 else
325 day_in_month_jg = day_in_month(month)
326 end if
327 if ( .not. wday > day_in_month_jg ) exit
328 wday = wday - day_in_month_jg
329 month = month + 1
330 if ( month > month_in_year ) then
331 month = 1
332 wyear = wyear + 1
333 end if
334 end do
335 case( cal_gregorian )
336 if ( wday > ychunk_e6 ) then
337 wyear = wyear + chunk_scale_e6 * aint( wday / ychunk_e6 )
338 wday = mod( wday, ychunk_e6 )
339 end if
340 if ( wday > ychunk_e3 ) then
341 wyear = wyear + chunk_scale_e3 * aint( wday / ychunk_e3 )
342 wday = mod( wday, ychunk_e3 )
343 end if
344 do
345 if ( month == 2 ) then
346 if ( mod( nint(wyear), 400 ) == 0 ) then
347 day_in_month_jg = 29
348 elseif ( mod( nint(wyear), 100 ) == 0 ) then
349 day_in_month_jg = 28
350 elseif ( mod( nint(wyear), 4 ) == 0 ) then
351 day_in_month_jg = 29
352 else
353 day_in_month_jg = 28
354 end if
355 else
356 day_in_month_jg = day_in_month(month)
357 end if
358 if ( .not. wday > day_in_month_jg ) exit
359 wday = wday - day_in_month_jg
360 month = month + 1
361 if ( month > month_in_year ) then
362 month = 1
363 wyear = wyear + 1
364 end if
365 end do
366 case default
367 if ( wday > ychunk_e6 ) then
368 wyear = wyear + chunk_scale_e6 * aint( wday / ychunk_e6 )
369 wday = mod( wday, ychunk_e6 )
370 end if
371 if ( wday > ychunk_e3 ) then
372 wyear = wyear + chunk_scale_e3 * aint( wday / ychunk_e3 )
373 wday = mod( wday, ychunk_e3 )
374 end if
375 do while ( wday > day_in_month(month) )
376 wday = wday - day_in_month(month)
377 month = month + 1
378 if ( month > month_in_year ) then
379 month = 1
380 wyear = wyear + 1
381 end if
382 end do
383 end select
384
385 year = int(wyear)
386 day = int(wday)
387 hour = int(whour)
388 min = int(wmin)
389
Derived types and parameters of calendar and date.
integer, parameter, public cal_user_defined
integer, parameter, public cal_julian
integer, parameter, public cal_gregorian
Error handling module.
Definition dc_error.f90:454
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
integer, parameter, public dc_einconsistcaldate
Definition dc_error.f90:553

References dc_calendar_types::cal_gregorian, dc_calendar_types::cal_julian, dc_calendar_types::cal_user_defined, dc_error::dc_einconsistcaldate, dc_error::dc_noerr, and dc_types::dp.

◆ dccaldate_str2ustr()

character(token) function, public dc_calendar_internal::dccaldate_str2ustr ( character(*), intent(in)  str)

Parse unit string and return unit string

Interprets the string given in str and returns the unit string. Case insensitive. Returns the first element of the unit array. Returns empty string for unrecognized unit.

Parameters
[in]strInput unit string
Returns
Standardized unit string

Definition at line 549 of file dc_calendar_internal.f90.

550 use dc_types, only: token
553 use dc_string, only: strieq
554 implicit none
555 character(*), intent(in):: str
556 character(TOKEN):: unit
557 integer :: unit_str_size, i
558 continue
559 unit = adjustl(str)
560
561 unit_str_size = size(unit_sec)
562 do i = 1, unit_str_size
563 if (strieq(trim(unit), trim(unit_sec(i)))) then
564 unit = unit_sec(1)
565 return
566 end if
567 end do
568
569 unit_str_size = size(unit_min)
570 do i = 1, unit_str_size
571 if (strieq(trim(unit), trim(unit_min(i)))) then
572 unit = unit_min(1)
573 return
574 end if
575 end do
576
577 unit_str_size = size(unit_hour)
578 do i = 1, unit_str_size
579 if (strieq(trim(unit), trim(unit_hour(i)))) then
580 unit = unit_hour(1)
581 return
582 end if
583 end do
584
585 unit_str_size = size(unit_day)
586 do i = 1, unit_str_size
587 if (strieq(trim(unit), trim(unit_day(i)))) then
588 unit = unit_day(1)
589 return
590 end if
591 end do
592
593 unit_str_size = size(unit_month)
594 do i = 1, unit_str_size
595 if (strieq(trim(unit), trim(unit_month(i)))) then
596 unit = unit_month(1)
597 return
598 end if
599 end do
600
601 unit_str_size = size(unit_year)
602 do i = 1, unit_str_size
603 if (strieq(trim(unit), trim(unit_year(i)))) then
604 unit = unit_year(1)
605 return
606 end if
607 end do
608
609 unit = ''
610
character(*), dimension(6), parameter, public unit_month
character(*), dimension(4), parameter, public unit_year
character(*), dimension(8), parameter, public unit_hour
character(*), dimension(8), parameter, public unit_sec
character(*), dimension(4), parameter, public unit_day
character(*), dimension(4), parameter, public unit_min
Handling character types.
Definition dc_string.f90:83
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public token
Character length for word, token
Definition dc_types.f90:128

References dc_types::token, dc_calendar_types::unit_day, dc_calendar_types::unit_hour, dc_calendar_types::unit_min, dc_calendar_types::unit_month, dc_calendar_types::unit_sec, and dc_calendar_types::unit_year.

◆ dccaldate_str2usym()

integer function, public dc_calendar_internal::dccaldate_str2usym ( character(*), intent(in)  str)

Parse unit string and return unit symbol

Interprets the string given in str and returns the unit symbol integer. Case insensitive. Returns UNIT_SYMBOL_ERR for unrecognized unit.

Parameters
[in]strInput unit string
Returns
Unit symbol integer

Definition at line 633 of file dc_calendar_internal.f90.

634 use dc_types, only: token
640 use dc_string, only: strieq
641 implicit none
642 character(*), intent(in):: str
643 integer:: symbol
644 integer:: unit_str_size, i
645 character(TOKEN):: unit
646 continue
647 unit = adjustl(str)
648
649 unit_str_size = size(unit_sec)
650 do i = 1, unit_str_size
651 if (strieq(trim(unit), trim(unit_sec(i)))) then
652 symbol = unit_symbol_sec
653 return
654 end if
655 end do
656
657 unit_str_size = size(unit_min)
658 do i = 1, unit_str_size
659 if (strieq(trim(unit), trim(unit_min(i)))) then
660 symbol = unit_symbol_min
661 return
662 end if
663 end do
664
665 unit_str_size = size(unit_hour)
666 do i = 1, unit_str_size
667 if (strieq(trim(unit), trim(unit_hour(i)))) then
668 symbol = unit_symbol_hour
669 return
670 end if
671 end do
672
673 unit_str_size = size(unit_day)
674 do i = 1, unit_str_size
675 if (strieq(trim(unit), trim(unit_day(i)))) then
676 symbol = unit_symbol_day
677 return
678 end if
679 end do
680
681 unit_str_size = size(unit_month)
682 do i = 1, unit_str_size
683 if (strieq(trim(unit), trim(unit_month(i)))) then
684 symbol = unit_symbol_month
685 return
686 end if
687 end do
688
689 unit_str_size = size(unit_year)
690 do i = 1, unit_str_size
691 if (strieq(trim(unit), trim(unit_year(i)))) then
692 symbol = unit_symbol_year
693 return
694 end if
695 end do
696
697 symbol = unit_symbol_err
698
integer, parameter, public unit_symbol_sec
integer, parameter, public unit_symbol_month
integer, parameter, public unit_symbol_year
integer, parameter, public unit_symbol_hour
integer, parameter, public unit_symbol_day
integer, parameter, public unit_symbol_min
integer, parameter, public unit_symbol_err

References dc_types::token, dc_calendar_types::unit_day, dc_calendar_types::unit_hour, dc_calendar_types::unit_min, dc_calendar_types::unit_month, dc_calendar_types::unit_sec, dc_calendar_types::unit_symbol_day, dc_calendar_types::unit_symbol_err, dc_calendar_types::unit_symbol_hour, dc_calendar_types::unit_symbol_min, dc_calendar_types::unit_symbol_month, dc_calendar_types::unit_symbol_sec, dc_calendar_types::unit_symbol_year, and dc_calendar_types::unit_year.

◆ dccaldate_ym2d()

integer function, public dc_calendar_internal::dccaldate_ym2d ( integer, intent(in)  year,
integer, intent(in)  month,
integer, intent(in)  day,
type(dc_cal), intent(in)  cal,
real(dp), intent(out)  day_of_year 
)

Convert year/month/day to day of year

Converts year/month/day to day of year according to calendar. Should be called after normalization by dccaldate_normalize.

Parameters
[in]yearYear
[in]monthMonth
[in]dayDay
[in]calCalendar object
[out]day_of_yearDay of year (double precision)
Returns
Status (DC_NOERR on success)

Definition at line 420 of file dc_calendar_internal.f90.

422 use dc_calendar_types, only: &
424 implicit none
425 integer:: stat
426 integer, intent(in):: year
427 integer, intent(in):: month
428 integer, intent(in):: day
429 real(DP), intent(out):: day_of_year
430 type(DC_CAL), intent(in):: cal
431
432 integer:: i
433
434 continue
435 stat = dc_noerr
436
437 select case( cal % cal_type )
438 case( cal_user_defined )
439 if ( month > cal % month_in_year ) stat = dc_einconsistcaldate
440 case default
441 if ( month > 12 ) stat = dc_einconsistcaldate
442 end select
443
444 if ( stat /= dc_noerr ) return
445
446 day_of_year = real( day, dp )
447
448 select case( cal % cal_type )
449 case( cal_julian )
450 do i = 1, month - 1
451 if ( i == 2 ) then
452 if ( mod( year, 4 ) == 0 ) then
453 day_of_year = day_of_year + 29
454 else
455 day_of_year = day_of_year + 28
456 end if
457 else
458 day_of_year = day_of_year + cal % day_in_month(i)
459 end if
460 end do
461 case( cal_gregorian )
462 do i = 1, month - 1
463 if ( i == 2 ) then
464 if ( mod( year, 400 ) == 0 ) then
465 day_of_year = day_of_year + 29
466 elseif ( mod( year, 100 ) == 0 ) then
467 day_of_year = day_of_year + 28
468 elseif ( mod( year, 4 ) == 0 ) then
469 day_of_year = day_of_year + 29
470 else
471 day_of_year = day_of_year + 28
472 end if
473 else
474 day_of_year = day_of_year + cal % day_in_month(i)
475 end if
476 end do
477 case default
478 do i = 1, month - 1
479 day_of_year = day_of_year + cal % day_in_month(i)
480 end do
481 end select
482

References dc_calendar_types::cal_gregorian, dc_calendar_types::cal_julian, dc_calendar_types::cal_user_defined, dc_error::dc_einconsistcaldate, dc_error::dc_noerr, and dc_types::dp.

◆ dccaltype_str()

character(token) function, public dc_calendar_internal::dccaltype_str ( integer, intent(in)  cal_type)

Convert calendar type integer to string

Converts integer calendar type to string representation. Returns empty string for invalid calendar type.

Parameters
[in]cal_typeCalendar type integer
Returns
Calendar type string

Definition at line 505 of file dc_calendar_internal.f90.

506 use dc_calendar_types, only: &
509 use dc_types, only: token
510 implicit none
511 character(TOKEN):: str
512 integer, intent(in):: cal_type
513
514 continue
515 select case( cal_type )
516 case(cal_user_defined) ; str = 'user_defined'
517 case(cal_cyclic) ; str = 'cyclic '
518 case(cal_noleap) ; str = 'noleap '
519 case(cal_julian) ; str = 'julian '
520 case(cal_gregorian) ; str = 'gregorian '
521 case(cal_360day) ; str = '360day '
522 case default ; str = ' '
523 end select
integer, parameter, public cal_360day
integer, parameter, public cal_noleap
integer, parameter, public cal_cyclic

References dc_calendar_types::cal_360day, dc_calendar_types::cal_cyclic, dc_calendar_types::cal_gregorian, dc_calendar_types::cal_julian, dc_calendar_types::cal_noleap, dc_calendar_types::cal_user_defined, and dc_types::token.

◆ default_cal_set()

subroutine, public dc_calendar_internal::default_cal_set

Set default calendar to Gregorian

When DCCal procedures are called without DC_CAL argument, this procedure is called first to set the default calendar to Gregorian calendar.

If default_cal is already initialized, this procedure does nothing and returns immediately.

Definition at line 105 of file dc_calendar_internal.f90.

107 implicit none
108 type(DC_CAL), pointer:: calp =>null()
109 continue
110 calp => default_cal
111
112 if ( calp % initialized ) return
113
114 calp % cal_type = cal_gregorian
115 calp % month_in_year = 12
116 calp % hour_in_day = 24
117 calp % min_in_hour = 60
118 calp % sec_in_min = 60.0_dp
119 allocate( calp % day_in_month(1:12) )
120 calp % day_in_month(1:12) = &
121 & (/ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 /)
122
123 calp % initialized = .true.
124 nullify( calp )

References dc_calendar_types::cal_gregorian, and default_cal.

Variable Documentation

◆ default_cal

dc_calendar_internal::default_cal

Default calendar object

Definition at line 66 of file dc_calendar_internal.f90.

66 type(DC_CAL), save, target, public:: default_cal

◆ default_date

dc_calendar_internal::default_date

Default date object

Definition at line 76 of file dc_calendar_internal.f90.

76 type(DC_CAL_DATE), save, target, public:: default_date