gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dccaldatedifference.f90
Go to the documentation of this file.
1! -*- mode: f90; coding: utf-8 -*-
2!-----------------------------------------------------------------------
3! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
4!-----------------------------------------------------------------------
21
52function dccaldatedifference1( start_date, end_date, cal ) result(sec)
53
57 use dc_types, only: dp
58 implicit none
59 real(dp):: sec
60 type(dc_cal_date), intent(in):: start_date
61 type(dc_cal_date), intent(in):: end_date
62 type(dc_cal), intent(in), optional, target:: cal
63
64 ! 作業変数
65 ! Work variables
66 !
67 type(dc_cal), pointer:: calp =>null()
68 real(dp):: start_year, start_day, start_sec, start_neg_offset_day
69 real(dp):: end_year, end_day, end_sec, end_neg_offset_day
70 integer:: day_in_4years, day_in_400years
71 integer:: start_year_int, end_year_int
72 integer:: i, j
73continue
74 ! オブジェクトのポインタ割付
75 ! Associate pointer of an object
76 !
77 if ( present( cal ) ) then
78 calp => cal
79 else
80 calp => default_cal
81 if ( .not. calp % initialized ) call default_cal_set
82 end if
83
84 ! 初期設定のチェック
85 ! Check initialization
86 !
87 if ( .not. calp % initialized ) then
88 sec = 0.0_dp
89 return
90 end if
91
92 if ( .not. start_date % initialized ) then
93 sec = 0.0_dp
94 return
95 end if
96
97 if ( .not. end_date % initialized ) then
98 sec = 0.0_dp
99 return
100 end if
101
102 start_neg_offset_day = 0
103 end_neg_offset_day = 0
104
105 start_year_int = start_date % year
106 end_year_int = end_date % year
107
108 ! 日への変換
109 ! Convert into days
110 !
111 select case( calp % cal_type )
112 case( cal_julian )
113
114 day_in_4years = 1461
115
116 ! 年が負の場合,400 年単位で引き算し下駄を履かせる
117 !
118 do while ( start_year_int < 1 )
119 start_neg_offset_day = start_neg_offset_day &
120 & + day_in_4years * 100
121 start_year_int = start_year_int &
122 & + 400
123 end do
124
125 ! start_date の日への変換
126 ! Convert start_date into days
127 !
128 if ( ( start_year_int - 1 ) > 4 ) then
129 start_day = int( ( start_year_int - 1 ) / 4 ) * day_in_4years
130 start_year = mod( start_year_int - 1, 4 ) + 1
131 else
132 start_day = 0
133 start_year = start_year_int
134 end if
135
136 start_day = start_day + ( start_year - 1 ) * sum( calp % day_in_month(:) )
137 do i = 1, start_date % month - 1
138 if ( int(start_year) == 4 .and. i == 2 ) then
139 start_day = start_day + 29
140 else
141 start_day = start_day + calp % day_in_month(i)
142 end if
143 end do
144 start_day = start_day + start_date % day
145
146 ! 年が負の場合,400 年単位で引き算し下駄を履かせる
147 !
148 do while ( end_year_int < 1 )
149 end_neg_offset_day = end_neg_offset_day &
150 & + day_in_4years * 100
151 end_year_int = end_year_int &
152 & + 400
153 end do
154
155 ! end_date の日への変換
156 ! Convert end_date into days
157 !
158 if ( ( end_year_int - 1 ) > 4 ) then
159 end_day = int( ( end_year_int - 1 ) / 4 ) * day_in_4years
160 end_year = mod( end_year_int - 1, 4 ) + 1
161 else
162 end_day = 0
163 end_year = end_year_int
164 end if
165
166 end_day = end_day + ( end_year - 1 ) * sum( calp % day_in_month(:) )
167 do i = 1, end_date % month - 1
168 if ( int(end_year) == 4 .and. i == 2 ) then
169 end_day = end_day + 29
170 else
171 end_day = end_day + calp % day_in_month(i)
172 end if
173 end do
174 end_day = end_day + end_date % day
175
176 case( cal_gregorian )
177
178 day_in_400years = 146097
179
180 ! 年が負の場合,400 年単位で引き算し下駄を履かせる
181 !
182 do while ( start_year_int < 1 )
183 start_neg_offset_day = start_neg_offset_day &
184 & + day_in_400years
185 start_year_int = start_year_int &
186 & + 400
187 end do
188
189 ! start_date の日への変換
190 ! Convert start_date into days
191 !
192 if ( ( start_year_int - 1 ) > 400 ) then
193 start_day = int( ( start_year_int - 1 ) / 400 ) * day_in_400years
194 start_year = mod( start_year_int - 1, 400 ) + 1
195 else
196 start_day = 0
197 start_year = start_year_int
198 end if
199
200 do j = 1, int( start_year - 1 )
201 do i = 1, calp % month_in_year
202 if ( i == 2 ) then
203 if ( mod( j, 400 ) == 0 ) then
204 start_day = start_day + 29
205 elseif ( mod( j, 100 ) == 0 ) then
206 start_day = start_day + 28
207 elseif ( mod( j, 4 ) == 0 ) then
208 start_day = start_day + 29
209 else
210 start_day = start_day + 28
211 end if
212 else
213 start_day = start_day + calp % day_in_month(i)
214 end if
215 end do
216 end do
217
218 do i = 1, start_date % month - 1
219 if ( i == 2 ) then
220 if ( mod( int(start_year), 400 ) == 0 ) then
221 start_day = start_day + 29
222 elseif ( mod( int(start_year), 100 ) == 0 ) then
223 start_day = start_day + 28
224 elseif ( mod( int(start_year), 4 ) == 0 ) then
225 start_day = start_day + 29
226 else
227 start_day = start_day + 28
228 end if
229 else
230 start_day = start_day + calp % day_in_month(i)
231 end if
232 end do
233
234 start_day = start_day + start_date % day
235
236 ! 年が負の場合,400 年単位で引き算し下駄を履かせる
237 !
238 do while ( end_year_int < 1 )
239 end_neg_offset_day = end_neg_offset_day &
240 & + day_in_400years
241 end_year_int = end_year_int &
242 & + 400
243 end do
244
245 ! end_date の日への変換
246 ! Convert end_date into days
247 !
248 if ( ( end_year_int - 1 ) > 400 ) then
249 end_day = int( ( end_year_int - 1 ) / 400 ) * day_in_400years
250 end_year = mod( end_year_int - 1, 400 ) + 1
251 else
252 end_day = 0
253 end_year = end_year_int
254 end if
255
256 do j = 1, int( end_year - 1 )
257 do i = 1, calp % month_in_year
258 if ( i == 2 ) then
259 if ( mod( j, 400 ) == 0 ) then
260 end_day = end_day + 29
261 elseif ( mod( j, 100 ) == 0 ) then
262 end_day = end_day + 28
263 elseif ( mod( j, 4 ) == 0 ) then
264 end_day = end_day + 29
265 else
266 end_day = end_day + 28
267 end if
268 else
269 end_day = end_day + calp % day_in_month(i)
270 end if
271 end do
272 end do
273
274 do i = 1, end_date % month - 1
275 if ( i == 2 ) then
276 if ( mod( int(end_year), 400 ) == 0 ) then
277 end_day = end_day + 29
278 elseif ( mod( int(end_year), 100 ) == 0 ) then
279 end_day = end_day + 28
280 elseif ( mod( int(end_year), 4 ) == 0 ) then
281 end_day = end_day + 29
282 else
283 end_day = end_day + 28
284 end if
285 else
286 end_day = end_day + calp % day_in_month(i)
287 end if
288 end do
289
290 end_day = end_day + end_date % day
291
292 case default
293 ! start_date の日への変換
294 ! Convert start_date into days
295 !
296 start_day = ( start_year_int - 1 ) * sum( calp % day_in_month(:) )
297 do i = 1, start_date % month - 1
298 start_day = start_day + calp % day_in_month(i)
299 end do
300 start_day = start_day + start_date % day
301
302 ! end_date の日への変換
303 ! Convert end_date into days
304 !
305 end_day = ( end_year_int - 1 ) * sum( calp % day_in_month(:) )
306 do i = 1, end_date % month - 1
307 end_day = end_day + calp % day_in_month(i)
308 end do
309 end_day = end_day + end_date % day
310 end select
311
312 ! start_date の秒への変換
313 ! Convert start_date into seconds
314 !
315 start_sec = ( start_day - 1 - start_neg_offset_day ) &
316 & * calp % hour_in_day &
317 & * calp % min_in_hour &
318 & * calp % sec_in_min &
319 & + start_date % hour * calp % min_in_hour &
320 & * calp % sec_in_min &
321 & + start_date % min * calp % sec_in_min &
322 & + start_date % sec
323
324 ! end_date の秒への変換
325 ! Convert end_date into seconds
326 !
327 end_sec = ( end_day - 1 - end_neg_offset_day ) &
328 & * calp % hour_in_day &
329 & * calp % min_in_hour &
330 & * calp % sec_in_min &
331 & + end_date % hour * calp % min_in_hour &
332 & * calp % sec_in_min &
333 & + end_date % min * calp % sec_in_min &
334 & + end_date % sec
335
336 ! 差分の計算
337 ! Calculate difference
338 !
339 sec = end_sec - start_sec
340
341 ! 終了処理, 例外処理
342 ! Termination and Exception handling
343 !
344 nullify( calp )
345end function dccaldatedifference1
346
347
348!!$
349!!$
350!!$subroutine DCCalConvertByUnit1( in_time, in_unit, out_unit, out_time, cal, err )
351!!$ use dc_calendar_internal, only: default_cal, default_cal_set, &
352!!$ & dccaltype_str, dccaldate_str2usym
353!!$ use dc_calendar_types, only: DC_CAL, &
354!!$ & UNIT_SYMBOL_YEAR, UNIT_SYMBOL_MONTH, UNIT_SYMBOL_DAY, &
355!!$ & UNIT_SYMBOL_HOUR, UNIT_SYMBOL_MIN, UNIT_SYMBOL_SEC
356!!$ use dc_error, only: StoreError, DC_NOERR, DC_EBADUNIT, DC_ENOTINIT
357!!$ use dc_message, only: MessageNotify
358!!$ use dc_trace, only: BeginSub, EndSub
359!!$ use dc_types, only: DP, TOKEN, STRING
360!!$ implicit none
361!!$ real(DP), intent(in):: in_time
362!!$ character(*), intent(in):: in_unit
363!!$ character(*), intent(in):: out_unit
364!!$ real(DP), intent(out):: out_time
365!!$ type(DC_CAL), intent(in), optional, target:: cal
366!!$ logical, intent(out), optional:: err
367!!$ ! 例外処理用フラグ.
368!!$ ! デフォルトでは, この手続き内でエラーが
369!!$ ! 生じた場合, プログラムは強制終了します.
370!!$ ! 引数 *err* が与えられる場合,
371!!$ ! プログラムは強制終了せず, 代わりに
372!!$ ! *err* に .true. が代入されます.
373!!$ !
374!!$ ! Exception handling flag.
375!!$ ! By default, when error occur in
376!!$ ! this procedure, the program aborts.
377!!$ ! If this *err* argument is given,
378!!$ ! .true. is substituted to *err* and
379!!$ ! the program does not abort.
380!!$
381!!$ ! 作業変数
382!!$ ! Work variables
383!!$ !
384!!$ type(DC_CAL), pointer:: calp =>null()
385!!$ real(DP):: in_timew
386!!$ integer:: in_unit_sym, out_unit_sym
387!!$ integer:: stat
388!!$ character(STRING):: cause_c
389!!$ character(*), parameter:: subname = 'DCCalConvertByUnit1'
390!!$continue
391!!$ call BeginSub( subname )
392!!$ stat = DC_NOERR
393!!$ cause_c = ''
394!!$
395!!$ ! オブジェクトのポインタ割付
396!!$ ! Associate pointer of an object
397!!$ !
398!!$ if ( present( cal ) ) then
399!!$ calp => cal
400!!$ else
401!!$ calp => default_cal
402!!$ if ( .not. calp % initialized ) call default_cal_set
403!!$ end if
404!!$
405!!$ ! 初期設定のチェック
406!!$ ! Check initialization
407!!$ !
408!!$ if ( .not. calp % initialized ) then
409!!$ stat = DC_ENOTINIT
410!!$ cause_c = 'DC_CAL'
411!!$ goto 999
412!!$ end if
413!!$
414!!$ ! 単位の解釈
415!!$ ! Parse units
416!!$ !
417!!$ in_unit_sym = dccaldate_str2usym( in_unit )
418!!$ out_unit_sym = dccaldate_str2usym( out_unit )
419!!$
420!!$ ! 数値の変換
421!!$ ! Convert a value
422!!$ !
423!!$ select case(in_unit_sym)
424!!$ case(UNIT_SYMBOL_DAY)
425!!$ in_timew = in_time * calp % hour_in_day &
426!!$ & * calp % min_in_hour &
427!!$ & * calp % sec_in_min
428!!$ case(UNIT_SYMBOL_HOUR)
429!!$ in_timew = in_time * calp % min_in_hour &
430!!$ & * calp % sec_in_min
431!!$ case(UNIT_SYMBOL_MIN)
432!!$ in_timew = in_time * calp % sec_in_min
433!!$ case(UNIT_SYMBOL_SEC)
434!!$ in_timew = in_time
435!!$ case default
436!!$ cause_c = in_unit
437!!$ call MessageNotify('W', subname, 'in_unit=<%c> is invalid. (ONLY day,hour,min,sec are valid)', &
438!!$ & c1 = trim(in_unit) )
439!!$ stat = DC_EBADUNIT
440!!$ goto 999
441!!$ end select
442!!$
443!!$ select case(out_unit_sym)
444!!$ case(UNIT_SYMBOL_DAY)
445!!$ out_time = in_timew / calp % hour_in_day &
446!!$ & / calp % min_in_hour &
447!!$ & / calp % sec_in_min
448!!$ case(UNIT_SYMBOL_HOUR)
449!!$ out_time = in_timew / calp % min_in_hour &
450!!$ & / calp % sec_in_min
451!!$ case(UNIT_SYMBOL_MIN)
452!!$ out_time = in_timew / calp % sec_in_min
453!!$ case(UNIT_SYMBOL_SEC)
454!!$ out_time = in_timew
455!!$ case default
456!!$ cause_c = out_unit
457!!$ call MessageNotify('W', subname, 'out_unit=<%c> is invalid. (ONLY day,hour,min,sec are valid)', &
458!!$ & c1 = trim(out_unit) )
459!!$ stat = DC_EBADUNIT
460!!$ goto 999
461!!$ end select
462!!$
463!!$ ! 終了処理, 例外処理
464!!$ ! Termination and Exception handling
465!!$ !
466!!$999 continue
467!!$ nullify( calp )
468!!$ call StoreError( stat, subname, err, cause_c )
469!!$ call EndSub( subname )
470!!$end subroutine DCCalConvertByUnit1
real(dp) function dccaldatedifference1(start_date, end_date, cal)
Evaluate difference of date.
Internal module for dc_calendar.
type(dc_cal), target, save, public default_cal
Default calendar object
subroutine, public default_cal_set
Derived types and parameters of calendar and date.
integer, parameter, public cal_julian
integer, parameter, public cal_gregorian
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92