gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
dc_calendar_internal.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
47
49
51 use dc_types, only: dp
52 implicit none
53 private
57
66 type(dc_cal), save, target, public:: default_cal
67
76 type(dc_cal_date), save, target, public:: default_date
77
78contains
79
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 )
125 end subroutine default_cal_set
126
127
177 function dccaldate_normalize( year, month, day, hour, min, sec, cal ) result(stat)
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
390 end function dccaldate_normalize
391
420 function dccaldate_ym2d( year, month, day, cal, day_of_year ) result(stat)
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
483 end function dccaldate_ym2d
484
485
505 function dccaltype_str( cal_type ) result(str)
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
524 end function dccaltype_str
525
526
549 function dccaldate_str2ustr(str) result(unit)
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
611 end function dccaldate_str2ustr
612
633 function dccaldate_str2usym(str) result(symbol)
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
699 end function dccaldate_str2usym
700
701end module dc_calendar_internal
dc_calendar用の内部モジュール
integer function, public dccaldate_normalize(year, month, day, hour, min, sec, cal)
integer function, public dccaldate_ym2d(year, month, day, cal, day_of_year)
type(dc_cal), target, save, public default_cal
デフォルトの暦. DCCal で始まる手続のうち, DC_CAL 型の省略可能引数が与えられない 場合にはこの暦が設定もしくは利用される.
character(token) function, public dccaldate_str2ustr(str)
character(token) function, public dccaltype_str(cal_type)
subroutine, public default_cal_set
integer function, public dccaldate_str2usym(str)
type(dc_cal_date), target, save, public default_date
デフォルトの日時. DCCalDate で始まる手続のうち, DC_CAL_DATE 型の省略可能引数が 与えられない場合にはこの日時が設定もしくは利用される.
暦と日時に関する構造データ型と定数
integer, parameter, public cal_user_defined
integer, parameter, public cal_julian
character(*), dimension(6), parameter, public unit_month
integer, parameter, public unit_symbol_sec
character(*), dimension(4), parameter, public unit_year
character(*), dimension(8), parameter, public unit_hour
integer, parameter, public cal_gregorian
character(*), dimension(8), parameter, public unit_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
character(*), dimension(4), parameter, public unit_day
character(*), dimension(4), parameter, public unit_min
integer, parameter, public unit_symbol_err
integer, parameter, public cal_360day
integer, parameter, public cal_noleap
integer, parameter, public cal_cyclic
エラー処理用モジュール
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
文字型変数の操作
Definition dc_string.f90:83
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public token
単語やキーワードを保持する文字型変数の種別型パラメタ
Definition dc_types.f90:128
integer, parameter, public dp
倍精度実数型変数
Definition dc_types.f90:92