gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
dc_calendar_internal Module Reference

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
 デフォルトの暦. DCCal で始まる手続のうち, DC_CAL 型の省略可能引数が与えられない 場合にはこの暦が設定もしくは利用される.
type(dc_cal_date), target, save, public default_date
 デフォルトの日時. DCCalDate で始まる手続のうち, DC_CAL_DATE 型の省略可能引数が 与えられない場合にはこの日時が設定もしくは利用される.

Detailed Description

dc_calendar用の内部モジュール

Author
Yasuhiro MORIKAWA

dc_calendar モジュール内で使用される内部向け定数, 変数, 手続き群を 提供します.

内部手続一覧

手続名 説明
default_cal_set デフォルトの暦をグレゴリオ暦に設定
dccaldate_normalize 日時情報の正規化
dccaldate_ym2d 年月日を年始からの通日に変換
dccaltype_str 暦タイプを文字列に変換
dccaldate_str2ustr 単位文字列を解釈し単位文字列を返す
dccaldate_str2usym 単位文字列を解釈し単位シンボルを返す

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 )

日時情報の正規化を行います

暦情報 cal に従い, 日時情報の正規化を行います. dc_calendar モジュール内部で使用されることを前提とします.

以下の場合に正規化を実施します:

  • sec が「1分の秒数」を超えている: 分に繰り上げ
  • min が「1時間の分数」を超えている: 時に繰り上げ
  • hour が「1日の時間数」を超えている: 日に繰り上げ
  • day が「1月の日数」を超えている: 月/年に繰り上げ
  • sec, min, hour, day が負: 上位の単位から借りる
  • day が 0: 上位の単位から借りる
Parameters
[in,out]year
[in,out]month
[in,out]day
[in,out]hour
[in,out]min
[in,out]sec
[in]cal暦情報を収めたオブジェクト
Returns
ステータス (成功時は DC_NOERR, エラー時は DC_EINCONSISTCALDATE)

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
暦と日時に関する構造データ型と定数
integer, parameter, public cal_user_defined
integer, parameter, public cal_julian
integer, parameter, public cal_gregorian
エラー処理用モジュール
Definition dc_error.f90:454
integer, parameter, public dc_noerr
エラー等を保持
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)

単位文字列を解釈し単位文字列を返します

引数 str に与えられた文字列を解釈し, 日時の単位を unit に返します. 大文字と小文字は区別されません. 返る文字列は単位配列の先頭の文字列です. 該当しない文字列の場合は空文字が返ります.

Parameters
[in]str入力単位文字列
Returns
標準化された単位文字列

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
文字型変数の操作
Definition dc_string.f90:83
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public 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)

単位文字列を解釈し単位シンボルを返します

引数 str に与えられた文字列を解釈し, 日時の単位を示す整数 symbol を返します. 大文字と小文字は区別しません. 該当しない文字列の場合は UNIT_SYMBOL_ERR が返ります.

Parameters
[in]str入力単位文字列
Returns
単位シンボル (整数)

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 )

年月日を年始からの通日に変換します

暦情報 cal に従い, 月日をその年が始まった時からの通日に変換します. 結果は倍精度実数として day_of_year に返ります. dccaldate_normalize によって正規化した後に呼び出してください.

Parameters
[in]year
[in]month
[in]day
[in]cal暦情報を収めたオブジェクト
[out]day_of_year年始からの通日 (倍精度実数)
Returns
ステータス (成功時は DC_NOERR)

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)

整数型の暦タイプを文字列に変換します

整数型の暦タイプ cal_type を文字列に変換します. 不正な cal_type の場合は空文字が返ります.

Parameters
[in]cal_type暦タイプ (整数)
Returns
暦タイプ文字列

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

デフォルトの暦をグレゴリオ暦として設定します

DCCal で始まる手続が呼び出され, DC_CAL 型の引数に暦の設定が 行われていない場合には, まずこの手続を呼び出して, デフォルトの暦 default_cal をグレゴリオ暦として設定します.

既に default_cal に暦が設定されている場合にはこの手続内で それを判定して何もせずに手続を終了するため, この手続は 何度呼び出しても良く, 呼び出す側で状態の有無を確認する 必要はありません.

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

type(dc_cal), target, save, public dc_calendar_internal::default_cal

デフォルトの暦. DCCal で始まる手続のうち, DC_CAL 型の省略可能引数が与えられない 場合にはこの暦が設定もしくは利用される.

Definition at line 66 of file dc_calendar_internal.f90.

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

◆ default_date

type(dc_cal_date), target, save, public dc_calendar_internal::default_date

デフォルトの日時. DCCalDate で始まる手続のうち, DC_CAL_DATE 型の省略可能引数が 与えられない場合にはこの日時が設定もしくは利用される.

Definition at line 76 of file dc_calendar_internal.f90.

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