gtool5 Fortran 90/95 ライブラリ 1.0.0-rc5
English
Loading...
Searching...
No Matches
dcdatetimeeval.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
4!>
5!> @file dcdatetimeeval.f90
6!> @author Yasuhiro MORIKAWA, Eizi TOYODA
7!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
8!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
9!> @en
10!> @brief Conversion from DC_DATETIME/DC_DIFFTIME to date/time components
11!> @details
12!> Procedures provided in this file are available through dc_date module.
13!> @enden
14!>
15!> @ja
16!> @brief DC_DATETIME/DC_DIFFTIME 型変数から月日秒への変換
17!> @details
18!> このファイルで提供される手続き群は dc_date モジュールにて提供されます.
19!> @endja
20!>
21
22!> @en
23!> @brief Convert DC_DATETIME to date/time components
24!> @details
25!> Converts DC_DATETIME variable `time` to year, month, day, hour,
26!> minute, second, calendar type, and timezone.
27!>
28!> @param[in] time DC_DATETIME variable to convert
29!> @param[out] year Year (optional)
30!> @param[out] mon Month (optional)
31!> @param[out] day Day (optional)
32!> @param[out] hour Hour (optional)
33!> @param[out] min Minute (optional)
34!> @param[out] sec Second (optional)
35!> @param[out] caltype Calendar type (optional)
36!> @param[out] zone Timezone (offset from UTC) (optional)
37!> @param[out] sclyear Year as DC_SCALED_SEC (optional)
38!> @param[out] sclmon Month as DC_SCALED_SEC (optional)
39!> @param[out] sclday Day as DC_SCALED_SEC (optional)
40!> @param[out] sclsec Second as DC_SCALED_SEC (optional)
41!> @enden
42!>
43!> @ja
44!> @brief DC_DATETIME を日時成分に変換
45!> @details
46!> DC_DATETIME 型変数 `time` を年, 月, 日, 時間, 分, 秒,
47!> 暦法, タイムゾーンに変換して返します.
48!>
49!> @param[in] time 変換する DC_DATETIME 型変数
50!> @param[out] year 年 (省略可能)
51!> @param[out] mon 月 (省略可能)
52!> @param[out] day 日 (省略可能)
53!> @param[out] hour 時 (省略可能)
54!> @param[out] min 分 (省略可能)
55!> @param[out] sec 秒 (省略可能)
56!> @param[out] caltype 暦法 (省略可能)
57!> @param[out] zone タイムゾーン (UTC からの時差) (省略可能)
58!> @param[out] sclyear 年 (DC_SCALED_SEC 型) (省略可能)
59!> @param[out] sclmon 月 (DC_SCALED_SEC 型) (省略可能)
60!> @param[out] sclday 日 (DC_SCALED_SEC 型) (省略可能)
61!> @param[out] sclsec 秒 (DC_SCALED_SEC 型) (省略可能)
62!> @endja
63subroutine dcdatetimeeval1(time, year, mon, day, hour, min, &
64 & sec, caltype, zone, sclyear, sclmon, sclday, sclsec)
65 use dc_types, only: dp
66 use dc_date_types, only: dc_datetime, &
70 use dc_scaledsec, only: dc_scaled_sec, &
71 & assignment(=), dcscaledsecputline, &
72 & operator(==), operator(>), operator(<), operator(>=), operator(<=), &
73 & operator(+), operator(-), operator(*), operator(/), mod, modulo, &
74 & abs, int, floor, ceiling
75 use dc_trace, only: beginsub, endsub
76 implicit none
77 type(dc_datetime), intent(in):: time
78 integer, intent(out), optional:: year ! 年
79 integer, intent(out), optional:: mon ! 月
80 integer, intent(out), optional:: day ! 日
81 integer, intent(out), optional:: hour ! 時
82 integer, intent(out), optional:: min ! 分
83 real(DP),intent(out), optional:: sec ! 秒
84 integer, intent(out), optional:: caltype ! 暦法
85 character(*), intent(out), optional:: zone ! タイムゾーン (UTC からの時差)
86 type(dc_scaled_sec), intent(out), optional:: sclyear ! 年 (DC_SCALED_SEC 型)
87 type(dc_scaled_sec), intent(out), optional:: sclmon ! 月 (DC_SCALED_SEC 型)
88 type(dc_scaled_sec), intent(out), optional:: sclday ! 日 (DC_SCALED_SEC 型)
89 type(dc_scaled_sec), intent(out), optional:: sclsec ! 秒 (DC_SCALED_SEC 型)
90
91 type(dc_scaled_sec):: iyear, month, iday, imon, isec
92 !character(*), parameter :: subname = 'DCDateTimeEval1'
93continue
94 !call BeginSub(subname)
95 if (present(zone)) then
96 zone = time % zone
97 end if
98 if (present(caltype)) then
99 caltype = time % caltype
100 end if
101 isec = time % sec
102 if (present(hour)) then
103 hour = floor(isec / hour_seconds)
104 isec = modulo(isec, hour_seconds)
105 end if
106 if (present(min)) then
107 min = floor(isec / min_seconds)
108 isec = modulo(isec, min_seconds)
109 end if
110 if (present(sec)) then
111 sec = isec
112 end if
113 if (present(sclsec)) then
114 sclsec = isec
115 end if
116
117 if (time % caltype == cal_cyclic) then
118 iday = time % day
119 if (present(year)) year = 0
120 if (present(sclyear)) sclyear = 0
121 if (present(sclmon)) then
122 sclmon = floor(iday / cyclic_mdays)
123 iday = ceiling( modulo(iday, cyclic_mdays) )
124 elseif (present(mon)) then
125 mon = floor(iday / cyclic_mdays)
126 iday = ceiling( modulo(iday, cyclic_mdays) )
127 end if
128 if (present(day)) day = iday
129 if (present(sclday)) sclday = iday
130 goto 999
131 endif
132 if (time % caltype == cal_noleap) then
133 iday = int( modulo(time%day - 91, year_days) )
134 iyear = int( (time%day - 91 - iday) / year_days )
135 else
136 if (time % caltype == cal_julian) then
137 iday = int( modulo(time%day - 92, four_years) )
138 iyear = int( (time%day - 92 - iday) / four_years ) * 4
139 elseif (time%day < 640196) then
140 iday = int( modulo(time%day - 92, four_years) )
141 iyear = int( (time%day - 92 - iday) / four_years ) * 4
142 else
143 iday = int( modulo(time%day - 94, four_century) )
144 iyear = int( (time%day - 94 - iday) / four_century ) * 400
145 if (iday == four_century - 1) then
146 iyear = iyear + 300
147 iday = 36525
148 else
149 iyear = iyear + int( iday / 36524 ) * 100
150 iday = int( modulo(iday, 36524) )
151 endif
152 iyear = iyear + int( iday / four_years ) * 4
153 iday = int( modulo(iday, four_years) )
154 endif
155 if (iday == four_years - 1) then
156 iyear = iyear + 3
157 iday = year_days
158 else
159 iyear = iyear + int( iday / year_days )
160 iday = int( modulo(iday, year_days) )
161 endif
162 endif
163
164 iday = iday * 10 + 922
165 month = int( iday / 306 )
166
167 if (present(sclyear)) then
168 imon = mod(month - 1, year_months) + 1
169 sclyear = iyear + int( (month - imon) / year_months )
170 elseif (present(year)) then
171 imon = mod(month - 1, year_months) + 1
172 year = iyear + int( (month - imon) / year_months )
173 else
174 imon = month
175 end if
176 if (present(sclmon)) then
177 iday = int( mod(iday, 306) / 10 ) + 1
178 sclmon = imon
179 elseif (present(mon)) then
180 iday = int( mod(iday, 306) / 10 ) + 1
181 mon = imon
182 else
183 iday = int( iday / 10 ) + 1
184 end if
185
186 if (present(day)) day = iday
187 if (present(sclday)) sclday = iday
188
189999 continue
190 !call EndSub(subname)
191end subroutine dcdatetimeeval1
192
193
194!> @en
195!> @brief Convert DC_DIFFTIME to time components
196!> @details
197!> Converts DC_DIFFTIME variable `diff` to year, month, day, hour,
198!> minute, second, and nondimensional time.
199!>
200!> @param[in] diff DC_DIFFTIME variable to convert
201!> @param[out] year Year (optional)
202!> @param[out] mon Month (optional)
203!> @param[out] day Day (optional)
204!> @param[out] hour Hour (optional)
205!> @param[out] min Minute (optional)
206!> @param[out] sec Second (optional)
207!> @param[out] nondim Nondimensional time (optional)
208!> @param[out] sclyear Year as DC_SCALED_SEC (optional)
209!> @param[out] sclmon Month as DC_SCALED_SEC (optional)
210!> @param[out] sclday Day as DC_SCALED_SEC (optional)
211!> @param[out] sclsec Second as DC_SCALED_SEC (optional)
212!> @param[out] sclnondim Nondimensional time as DC_SCALED_SEC (optional)
213!> @param[out] err Error flag (optional)
214!> @enden
215!>
216!> @ja
217!> @brief DC_DIFFTIME を時間成分に変換
218!> @details
219!> DC_DIFFTIME 型変数 `diff` を年, 月, 日, 時間, 分, 秒,
220!> 無次元時間に変換して返します.
221!>
222!> @param[in] diff 変換する DC_DIFFTIME 型変数
223!> @param[out] year 年 (省略可能)
224!> @param[out] mon 月 (省略可能)
225!> @param[out] day 日 (省略可能)
226!> @param[out] hour 時 (省略可能)
227!> @param[out] min 分 (省略可能)
228!> @param[out] sec 秒 (省略可能)
229!> @param[out] nondim 無次元時間 (省略可能)
230!> @param[out] sclyear 年 (DC_SCALED_SEC 型) (省略可能)
231!> @param[out] sclmon 月 (DC_SCALED_SEC 型) (省略可能)
232!> @param[out] sclday 日 (DC_SCALED_SEC 型) (省略可能)
233!> @param[out] sclsec 秒 (DC_SCALED_SEC 型) (省略可能)
234!> @param[out] sclnondim 無次元時間 (DC_SCALED_SEC 型) (省略可能)
235!> @param[out] err エラーフラグ (省略可能)
236!> @endja
237subroutine dcdifftimeeval1(diff, &
238 & year, mon, day, hour, min, sec, nondim, &
239 & sclyear, sclmon, sclday, sclsec, sclnondim, err)
240 use dc_types, only: dp
241 use dc_trace, only: beginsub, endsub
243 use dc_date_types, only: dc_difftime, &
245 use dc_scaledsec, only: dc_scaled_sec, &
246 & assignment(=), dcscaledsecputline, &
247 & operator(==), operator(>), operator(<), operator(>=), operator(<=), &
248 & operator(+), operator(-), operator(*), operator(/), mod, modulo, &
249 & abs, int, floor, ceiling
250 implicit none
251 type(dc_difftime), intent(in):: diff
252 integer, intent(out), optional:: year ! 年
253 integer, intent(out), optional:: mon ! 月
254 integer, intent(out), optional:: day ! 日
255 integer, intent(out), optional:: hour ! 時
256 integer, intent(out), optional:: min ! 分
257 real(DP),intent(out), optional:: sec ! 秒
258 real(DP),intent(out), optional:: nondim ! 無次元時間. Nondimensional time
259 type(dc_scaled_sec), intent(out), optional:: sclyear ! 年 (DC_SCALED_SEC 型)
260 type(dc_scaled_sec), intent(out), optional:: sclmon ! 月 (DC_SCALED_SEC 型)
261 type(dc_scaled_sec), intent(out), optional:: sclday ! 日 (DC_SCALED_SEC 型)
262 type(dc_scaled_sec), intent(out), optional:: sclsec ! 秒 (DC_SCALED_SEC 型)
263 type(dc_scaled_sec), intent(out), optional:: sclnondim ! 無次元時間 (DC_SCALED_SEC 型)
264 logical, intent(out), optional :: err
265 type(dc_scaled_sec):: imon, isec
266 integer:: stat
267 character(*), parameter :: subname = 'DCDiffTimeEval1'
268continue
269 !call BeginSub(subname)
270 stat = dc_noerr
271 if ( present(sclnondim) ) then
272 if ( .not. diff % nondim_flag ) then
273 stat = dc_edimtime
274 goto 999
275 end if
276 sclnondim = diff % sec
277 elseif ( present(nondim) ) then
278 if ( .not. diff % nondim_flag ) then
279 stat = dc_edimtime
280 goto 999
281 end if
282 nondim = diff % sec
283 else
284 if ( diff % nondim_flag ) then
285 stat = dc_enodimtime
286 goto 999
287 end if
288 end if
289
290 imon = diff % mon
291 isec = diff % sec
292 if (present(sclyear)) then
293 sclyear = int( imon / year_months )
294 imon = mod(imon, year_months)
295 elseif (present(year)) then
296 year = int( imon / year_months )
297 imon = mod(imon, year_months)
298 endif
299
300 if (present(sclmon)) then
301 sclmon = imon
302 elseif (present(mon)) then
303 mon = imon
304 endif
305
306 if (present(sclday)) then
307 sclday = diff % day
308 elseif (present(day)) then
309 day = diff % day
310 else
311 isec = isec + diff % day * diff % day_seconds
312 endif
313
314 if (present(hour)) then
315 hour = int(isec / hour_seconds)
316 isec = mod(isec, hour_seconds)
317 endif
318 if (present(min)) then
319 min = int(isec / min_seconds)
320 isec = mod(isec, min_seconds)
321 endif
322
323 if (present(sec)) then
324 sec = isec
325 endif
326 if (present(sclsec)) then
327 sclsec = isec
328 endif
329999 continue
330 call storeerror(stat, subname, err)
331 !call EndSub(subname)
332end subroutine dcdifftimeeval1
333
334
335!> @en
336!> @brief Convert DC_DATETIME to days
337!> @details
338!> Converts DC_DATETIME variable to number of days as double precision real.
339!> (e.g., 12 hours is converted to 0.5 days)
340!>
341!> @param[in] time DC_DATETIME variable to convert
342!> @return Number of days as double precision real
343!> @enden
344!>
345!> @ja
346!> @brief DC_DATETIME を日数に変換
347!> @details
348!> DC_DATETIME 型変数の日時を日数に換算して倍精度実数型変数で返します.
349!> (例えば 12 時間は 0.5 日と換算されます)
350!>
351!> @param[in] time 変換する DC_DATETIME 型変数
352!> @return 日数 (倍精度実数型)
353!> @endja
354function dcdatetimeevalday(time) result(result)
355 use dc_types, only: dp
356 use dc_date_generic, only: eval
357 use dc_date_types, only: dc_datetime
358 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), operator(+)
359 implicit none
360 real(dp):: result
361 type(dc_datetime), intent(in):: time
362 type(dc_scaled_sec):: day, sec
363continue
364 call eval(time, sclday = day, sclsec = sec)
365 result = day + sec / time % day_seconds
366end function dcdatetimeevalday
367
368!> @en
369!> @brief Convert DC_DIFFTIME to days
370!> @details
371!> Converts DC_DIFFTIME variable to number of days as double precision real.
372!> (e.g., 12 hours is converted to 0.5 days)
373!>
374!> One month is converted using dc_date_types#CYCLIC_MDAYS.
375!>
376!> @param[in] diff DC_DIFFTIME variable to convert
377!> @return Number of days as double precision real
378!> @enden
379!>
380!> @ja
381!> @brief DC_DIFFTIME を日数に変換
382!> @details
383!> DC_DIFFTIME 型変数の日時を日数に換算して倍精度実数型変数で返します.
384!> (例えば 12 時間は 0.5 日と換算されます)
385!>
386!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
387!>
388!> @param[in] diff 変換する DC_DIFFTIME 型変数
389!> @return 日数 (倍精度実数型)
390!> @endja
391function dcdifftimeevalday(diff) result(result)
392 use dc_types, only: dp
393 use dc_date_generic, only: eval
395 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), &
396 & operator(+), operator(*), int
397 implicit none
398 real(dp):: result
399 type(dc_difftime), intent(in):: diff
400 type(dc_scaled_sec):: day, mon, sec
401continue
402 call eval(diff, sclmon = mon, sclday = day, sclsec = sec)
403 result = int(mon * cyclic_mdays) + day + sec / diff % day_seconds
404end function dcdifftimeevalday
405
406
407!> @en
408!> @brief Convert DC_DATETIME to hours
409!> @details
410!> Converts DC_DATETIME variable to hours as double precision real.
411!> (e.g., 2 days is 48 hours, 30 minutes is 0.5 hours)
412!>
413!> @param[in] time DC_DATETIME variable to convert
414!> @return Number of hours as double precision real
415!> @enden
416!>
417!> @ja
418!> @brief DC_DATETIME を時間に変換
419!> @details
420!> DC_DATETIME 型変数の日時を時間に換算して倍精度実数型変数で返します.
421!> (例えば 2 日は 48 時間に, 30 分は 0.5 時間と換算されます)
422!>
423!> @param[in] time 変換する DC_DATETIME 型変数
424!> @return 時間 (倍精度実数型)
425!> @endja
426function dcdatetimeevalhour(time) result(result)
427 use dc_types, only: dp
428 use dc_date_generic, only: eval
430 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), &
431 & operator(+), operator(*), int
432 implicit none
433 real(dp):: result
434 type(dc_datetime), intent(in):: time
435 type(dc_scaled_sec):: day, sec
436continue
437 call eval(time, sclday = day, sclsec = sec)
438 result = (day * time % day_seconds + sec) / hour_seconds
439end function dcdatetimeevalhour
440
441!> @en
442!> @brief Convert DC_DIFFTIME to hours
443!> @details
444!> Converts DC_DIFFTIME variable to hours as double precision real.
445!> (e.g., 2 days is 48 hours, 30 minutes is 0.5 hours)
446!>
447!> One month is converted using dc_date_types#CYCLIC_MDAYS.
448!>
449!> @param[in] diff DC_DIFFTIME variable to convert
450!> @return Number of hours as double precision real
451!> @enden
452!>
453!> @ja
454!> @brief DC_DIFFTIME を時間に変換
455!> @details
456!> DC_DIFFTIME 型変数の日時を時間に換算して倍精度実数型変数で返します.
457!> (例えば 2 日は 48 時間に, 30 分は 0.5 時間と換算されます)
458!>
459!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
460!>
461!> @param[in] diff 変換する DC_DIFFTIME 型変数
462!> @return 時間 (倍精度実数型)
463!> @endja
464function dcdifftimeevalhour(diff) result(result)
465 use dc_types, only: dp
466 use dc_date_generic, only: eval
468 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), &
469 & operator(+), operator(*), int
470 implicit none
471 real(dp):: result
472 type(dc_difftime), intent(in):: diff
473 type(dc_scaled_sec):: mon, day, sec
474continue
475 call eval(diff, sclmon = mon, sclday = day, sclsec = sec)
476 result = ( int(mon * cyclic_mdays) + day &
477 & * diff % day_seconds + sec) / hour_seconds
478end function dcdifftimeevalhour
479
480
481!> @en
482!> @brief Convert DC_DATETIME to minutes
483!> @details
484!> Converts DC_DATETIME variable to minutes as double precision real.
485!> (e.g., 1 day is 1440 minutes, 30 seconds is 0.5 minutes)
486!>
487!> @param[in] time DC_DATETIME variable to convert
488!> @return Number of minutes as double precision real
489!> @enden
490!>
491!> @ja
492!> @brief DC_DATETIME を分に変換
493!> @details
494!> DC_DATETIME 型変数の日時を分に換算して倍精度実数型変数で返します.
495!> (例えば 1 日は 1440 分に, 30 秒は 0.5 分と換算されます)
496!>
497!> @param[in] time 変換する DC_DATETIME 型変数
498!> @return 分 (倍精度実数型)
499!> @endja
500function dcdatetimeevalmin(time) result(result)
501 use dc_types, only: dp
502 use dc_date_generic, only: eval
504 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), &
505 & operator(+), operator(*), int
506 implicit none
507 real(dp):: result
508 type(dc_datetime), intent(in):: time
509 type(dc_scaled_sec):: day, sec
510continue
511 call eval(time, sclday = day, sclsec = sec)
512 result = (day * time % day_seconds + sec) / min_seconds
513end function dcdatetimeevalmin
514
515!> @en
516!> @brief Convert DC_DIFFTIME to minutes
517!> @details
518!> Converts DC_DIFFTIME variable to minutes as double precision real.
519!> (e.g., 1 day is 1440 minutes, 30 seconds is 0.5 minutes)
520!>
521!> One month is converted using dc_date_types#CYCLIC_MDAYS.
522!>
523!> @param[in] diff DC_DIFFTIME variable to convert
524!> @return Number of minutes as double precision real
525!> @enden
526!>
527!> @ja
528!> @brief DC_DIFFTIME を分に変換
529!> @details
530!> DC_DIFFTIME 型変数の日時を分に換算して倍精度実数型変数で返します.
531!> (例えば 1 日は 1440 分に, 30 秒は 0.5 分と換算されます)
532!>
533!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
534!>
535!> @param[in] diff 変換する DC_DIFFTIME 型変数
536!> @return 分 (倍精度実数型)
537!> @endja
538function dcdifftimeevalmin(diff) result(result)
539 use dc_types, only: dp
540 use dc_date_generic, only: eval
542 use dc_scaledsec, only: dc_scaled_sec, assignment(=), operator(/), &
543 & operator(+), operator(*), int
544 implicit none
545 real(dp):: result
546 type(dc_difftime), intent(in):: diff
547 type(dc_scaled_sec):: mon, day, sec
548continue
549 call eval(diff, sclmon = mon, sclday = day, sclsec = sec)
550 result = ( int(mon * cyclic_mdays) + day &
551 & * diff % day_seconds + sec) / min_seconds
552end function dcdifftimeevalmin
553
554
555!> @en
556!> @brief Convert DC_DATETIME to seconds
557!> @details
558!> Converts DC_DATETIME variable to seconds as double precision real.
559!>
560!> @warning The year component is ignored. i.e., time containing 1999-01-01
561!> and time containing 2007-01-01 return the same value.
562!> (This may not be the desired behavior)
563!>
564!> @param[in] time DC_DATETIME variable to convert
565!> @return Number of seconds as double precision real
566!> @enden
567!>
568!> @ja
569!> @brief DC_DATETIME を秒に変換
570!> @details
571!> DC_DATETIME 型変数の日時を秒に換算して倍精度実数型変数で返します.
572!>
573!> @warning 年の要素は無視されます. すなわち, 1999-01-01 が格納された time と
574!> 2007-01-01 が格納された time からは同じ値が返ります.
575!> (これはもしかすると望ましくない動作かもしれません)
576!>
577!> @param[in] time 変換する DC_DATETIME 型変数
578!> @return 秒 (倍精度実数型)
579!> @endja
580function dcdatetimeevalsec(time) result(result)
581 use dc_types, only: dp
582 use dc_date_generic, only: eval
583 use dc_date_types, only: dc_datetime
584 use dc_scaledsec, only: assignment(=)
585 implicit none
586 real(dp):: result
587 type(dc_datetime), intent(in):: time
588 integer:: day
589 real(dp):: sec, day_seconds
590continue
591 call eval(time, day = day, sec = sec)
592 day_seconds = time % day_seconds
593 result = day * day_seconds + sec
594end function dcdatetimeevalsec
595
596!> @en
597!> @brief Convert DC_DIFFTIME to seconds
598!> @details
599!> Converts DC_DIFFTIME variable to seconds as double precision real.
600!>
601!> One month is converted using dc_date_types#CYCLIC_MDAYS.
602!>
603!> @param[in] diff DC_DIFFTIME variable to convert
604!> @return Number of seconds as double precision real
605!> @enden
606!>
607!> @ja
608!> @brief DC_DIFFTIME を秒に変換
609!> @details
610!> DC_DIFFTIME 型変数の日時を秒に換算して倍精度実数型変数で返します.
611!>
612!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
613!>
614!> @param[in] diff 変換する DC_DIFFTIME 型変数
615!> @return 秒 (倍精度実数型)
616!> @endja
617function dcdifftimeevalsec(diff) result(result)
618 use dc_types, only: dp
619 use dc_date_generic, only: eval
621 use dc_scaledsec, only: assignment(=)
622 implicit none
623 real(dp):: result
624 type(dc_difftime), intent(in):: diff
625 integer:: mon, day
626 real(dp):: sec, day_seconds
627continue
628 if ( .not. diff % nondim_flag ) then
629 call eval(diff, mon = mon, day = day, sec = sec)
630 day_seconds = diff % day_seconds
631 result = int(mon * cyclic_mdays) + day * day_seconds + sec
632 else
633 call eval(diff, nondim = result)
634 end if
635end function dcdifftimeevalsec
636
637!> @en
638!> @brief Convert DC_DIFFTIME to nondimensional time
639!> @details
640!> Converts DC_DIFFTIME variable to nondimensional time as double precision real.
641!>
642!> One month is converted using dc_date_types#CYCLIC_MDAYS.
643!>
644!> @param[in] diff DC_DIFFTIME variable to convert
645!> @return Nondimensional time as double precision real
646!> @enden
647!>
648!> @ja
649!> @brief DC_DIFFTIME を無次元時間に変換
650!> @details
651!> DC_DIFFTIME 型変数の日時を無次元時間に換算して倍精度実数型変数で返します.
652!>
653!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
654!>
655!> @param[in] diff 変換する DC_DIFFTIME 型変数
656!> @return 無次元時間 (倍精度実数型)
657!> @endja
658function dcdifftimeevalnondim(diff) result(result)
659 use dc_types, only: dp
660 use dc_date_generic, only: eval
661 use dc_date_types, only: dc_difftime
662 implicit none
663 real(dp):: result
664 type(dc_difftime), intent(in):: diff
665 real(dp):: nondim
666continue
667 call eval(diff, nondim=nondim)
668 result = nondim
669end function dcdifftimeevalnondim
670
671!> @en
672!> @brief Convert DC_DATETIME to seconds as DC_SCALED_SEC
673!> @details
674!> Converts DC_DATETIME variable to seconds as DC_SCALED_SEC type.
675!>
676!> @warning The year component is ignored. i.e., time containing 1999-01-01
677!> and time containing 2007-01-01 return the same value.
678!> (This may not be the desired behavior)
679!>
680!> @param[in] time DC_DATETIME variable to convert
681!> @return Seconds as DC_SCALED_SEC type
682!> @enden
683!>
684!> @ja
685!> @brief DC_DATETIME を秒に変換 (DC_SCALED_SEC 型)
686!> @details
687!> DC_DATETIME 型変数の日時を秒に換算して DC_SCALED_SEC 型で返します.
688!>
689!> @warning 年の要素は無視されます. すなわち, 1999-01-01 が格納された time と
690!> 2007-01-01 が格納された time からは同じ値が返ります.
691!> (これはもしかすると望ましくない動作かもしれません)
692!>
693!> @param[in] time 変換する DC_DATETIME 型変数
694!> @return 秒 (DC_SCALED_SEC 型)
695!> @endja
696function dcdatetimeevalsclsec(time) result(result)
697 use dc_date_generic, only: eval
698 use dc_date_types, only: dc_datetime
699 use dc_scaledsec, only: dc_scaled_sec, operator(/), &
700 & operator(+), operator(*), int
701 implicit none
702 type(dc_scaled_sec):: result
703 type(dc_datetime), intent(in):: time
704 type(dc_scaled_sec):: day, sec
705continue
706 call eval(time, sclday = day, sclsec = sec)
707 result = day * time % day_seconds + sec
708end function dcdatetimeevalsclsec
709
710!> @en
711!> @brief Convert DC_DIFFTIME to seconds as DC_SCALED_SEC
712!> @details
713!> Converts DC_DIFFTIME variable to seconds as DC_SCALED_SEC type.
714!>
715!> One month is converted using dc_date_types#CYCLIC_MDAYS.
716!>
717!> @param[in] diff DC_DIFFTIME variable to convert
718!> @return Seconds as DC_SCALED_SEC type
719!> @enden
720!>
721!> @ja
722!> @brief DC_DIFFTIME を秒に変換 (DC_SCALED_SEC 型)
723!> @details
724!> DC_DIFFTIME 型変数の日時を秒に換算して DC_SCALED_SEC 型で返します.
725!>
726!> 1 ヶ月は dc_date_types#CYCLIC_MDAYS と換算します.
727!>
728!> @param[in] diff 変換する DC_DIFFTIME 型変数
729!> @return 秒 (DC_SCALED_SEC 型)
730!> @endja
731function dcdifftimeevalsclsec(diff) result(result)
732 use dc_date_generic, only: eval
734 use dc_scaledsec, only: dc_scaled_sec, operator(/), &
735 & operator(==), operator(+), operator(*), int
736 implicit none
737 type(dc_scaled_sec):: result
738 type(dc_difftime), intent(in):: diff
739 type(dc_scaled_sec):: mon, day, sec
740 type(dc_scaled_sec):: zero_sec
741continue
742 if ( .not. diff % nondim_flag ) then
743 call eval(diff, sclmon = mon, sclday = day, sclsec = sec)
744 if ( mon == zero_sec ) then
745 result = day * diff % day_seconds + sec
746 else
747 result = ( int(mon * cyclic_mdays) + day ) * diff % day_seconds + sec
748 end if
749 else
750 call eval(diff, sclnondim = sec)
751 result = sec
752 end if
753end function dcdifftimeevalsclsec
754
755!> @en
756!> @brief Convert DC_DATETIME by specified unit
757!> @details
758!> Converts DC_DATETIME variable to the specified unit and returns
759!> as double precision real.
760!>
761!> For `unit`, the following values can be specified:
762!> - dc_date_types#UNIT_DAY (day)
763!> - dc_date_types#UNIT_HOUR (hour)
764!> - dc_date_types#UNIT_MIN (minute)
765!> - dc_date_types#UNIT_SEC (second)
766!>
767!> For `unit_symbol`, the following values can be specified:
768!> - dc_date_types#UNIT_SYMBOL_DAY (day)
769!> - dc_date_types#UNIT_SYMBOL_HOUR (hour)
770!> - dc_date_types#UNIT_SYMBOL_MIN (minute)
771!> - dc_date_types#UNIT_SYMBOL_SEC (second)
772!>
773!> Returns 0.0 if invalid unit is specified or neither argument is given.
774!>
775!> @param[in] time DC_DATETIME variable to convert
776!> @param[in] unit Unit string
777!> @param[in] unit_symbol Unit symbol constant (optional)
778!> @return Converted value as double precision real
779!> @enden
780!>
781!> @ja
782!> @brief DC_DATETIME を指定単位で変換
783!> @details
784!> DC_DATETIME 型変数の日時を `unit` または `unit_symbol` の単位に
785!> 換算して倍精度実数型変数で返します.
786!>
787!> `unit` には以下を与えることが可能です:
788!> - dc_date_types#UNIT_DAY (日)
789!> - dc_date_types#UNIT_HOUR (時)
790!> - dc_date_types#UNIT_MIN (分)
791!> - dc_date_types#UNIT_SEC (秒)
792!>
793!> `unit_symbol` には以下を与えることが可能です:
794!> - dc_date_types#UNIT_SYMBOL_DAY (日)
795!> - dc_date_types#UNIT_SYMBOL_HOUR (時)
796!> - dc_date_types#UNIT_SYMBOL_MIN (分)
797!> - dc_date_types#UNIT_SYMBOL_SEC (秒)
798!>
799!> これらに該当しないものを与えた場合, または引数を両方とも与えない場合,
800!> 0.0 が返ります.
801!>
802!> @param[in] time 変換する DC_DATETIME 型変数
803!> @param[in] unit 単位文字列
804!> @param[in] unit_symbol 単位記号定数 (省略可能)
805!> @return 変換された値 (倍精度実数型)
806!> @endja
807function dcdatetimeevalbyunit(time, unit, unit_symbol) result(result)
808 use dc_types, only: dp
810 use dc_date_types, only: dc_datetime, &
813 implicit none
814 real(dp):: result
815 type(dc_datetime), intent(in):: time
816 character(*), intent(in):: unit
817 integer, intent(in), optional:: unit_symbol
818 integer:: symbol
819continue
820 symbol = unit_symbol_err
821 if ( present(unit_symbol) ) then
822 symbol = unit_symbol
823 else
824 symbol = parsetimeunits(unit)
825 end if
826
827 if ( symbol == unit_symbol_sec ) then
828 result = evalsec(time)
829 elseif ( symbol == unit_symbol_min ) then
830 result = evalmin(time)
831 elseif ( symbol == unit_symbol_hour ) then
832 result = evalhour(time)
833 elseif ( symbol == unit_symbol_day ) then
834 result = evalday(time)
835 else
836 result = 0.0_dp
837 end if
838end function dcdatetimeevalbyunit
839
840
841!> @en
842!> @brief Convert DC_DIFFTIME by specified unit
843!> @details
844!> Converts DC_DIFFTIME variable to the specified unit and returns
845!> as double precision real.
846!>
847!> For `unit`, the following values can be specified:
848!> - dc_date_types#UNIT_DAY (day)
849!> - dc_date_types#UNIT_HOUR (hour)
850!> - dc_date_types#UNIT_MIN (minute)
851!> - dc_date_types#UNIT_SEC (second)
852!> - dc_date_types#UNIT_NONDIM (nondimensional)
853!>
854!> For `unit_symbol`, the following values can be specified:
855!> - dc_date_types#UNIT_SYMBOL_DAY (day)
856!> - dc_date_types#UNIT_SYMBOL_HOUR (hour)
857!> - dc_date_types#UNIT_SYMBOL_MIN (minute)
858!> - dc_date_types#UNIT_SYMBOL_SEC (second)
859!> - dc_date_types#UNIT_SYMBOL_NONDIM (nondimensional)
860!>
861!> Returns 0.0 if invalid unit is specified or neither argument is given.
862!>
863!> @param[in] diff DC_DIFFTIME variable to convert
864!> @param[in] unit Unit string
865!> @param[in] unit_symbol Unit symbol constant (optional)
866!> @return Converted value as double precision real
867!> @enden
868!>
869!> @ja
870!> @brief DC_DIFFTIME を指定単位で変換
871!> @details
872!> DC_DIFFTIME 型変数の日時を `unit` の単位に換算して
873!> 倍精度実数型変数で返します.
874!>
875!> `unit` には以下を与えることが可能です:
876!> - dc_date_types#UNIT_DAY (日)
877!> - dc_date_types#UNIT_HOUR (時)
878!> - dc_date_types#UNIT_MIN (分)
879!> - dc_date_types#UNIT_SEC (秒)
880!> - dc_date_types#UNIT_NONDIM (無次元時間)
881!>
882!> `unit_symbol` には以下を与えることが可能です:
883!> - dc_date_types#UNIT_SYMBOL_DAY (日)
884!> - dc_date_types#UNIT_SYMBOL_HOUR (時)
885!> - dc_date_types#UNIT_SYMBOL_MIN (分)
886!> - dc_date_types#UNIT_SYMBOL_SEC (秒)
887!> - dc_date_types#UNIT_SYMBOL_NONDIM (無次元時間)
888!>
889!> これらに該当しないものを与えた場合, または引数を両方とも与えない場合,
890!> 0.0 が返ります.
891!>
892!> @param[in] diff 変換する DC_DIFFTIME 型変数
893!> @param[in] unit 単位文字列
894!> @param[in] unit_symbol 単位記号定数 (省略可能)
895!> @return 変換された値 (倍精度実数型)
896!> @endja
897function dcdifftimeevalbyunit(diff, unit, unit_symbol) result(result)
898 use dc_types, only: dp
901 use dc_date_types, only: dc_difftime, &
904 implicit none
905 real(dp):: result
906 type(dc_difftime), intent(in):: diff
907 character(*), intent(in):: unit
908 integer, intent(in), optional:: unit_symbol
909 integer:: symbol
910continue
911 symbol = unit_symbol_err
912 if ( present(unit_symbol) ) then
913 symbol = unit_symbol
914 else
915 symbol = parsetimeunits(unit)
916 end if
917
918 if ( symbol == unit_symbol_nondim ) then
919 result = evalnondim(diff)
920 elseif ( symbol == unit_symbol_sec ) then
921 result = evalsec(diff)
922 elseif ( symbol == unit_symbol_min ) then
923 result = evalmin(diff)
924 elseif ( symbol == unit_symbol_hour ) then
925 result = evalhour(diff)
926 elseif ( symbol == unit_symbol_day ) then
927 result = evalday(diff)
928 else
929 result = 0.0_dp
930 end if
931end function dcdifftimeevalbyunit
932
933
934
935!!$subroutine DCDateTimeEval0(time, mon, day, sec)
936!!$ !
937!!$ ! dc_date_types#DC_DATETIME 型変数の *time* を
938!!$ ! 月 *mon*, 日 *day*, 秒 *sec* に変換して返す.
939!!$ !
940!!$ use dc_types, only: DP
941!!$ use dc_date_types, only: DC_DATETIME, &
942!!$ & CYCLIC_MDAYS, CAL_NOLEAP, CAL_JULIAN, CAL_CYCLIC, &
943!!$ & FOUR_YEARS, FOUR_CENTURY
944!!$ use dc_trace, only: BeginSub, EndSub
945!!$ implicit none
946!!$ type(DC_DATETIME), intent(in):: time
947!!$ integer, intent(out):: mon, day
948!!$ real(DP), intent(out):: sec
949!!$ integer:: year, month
950!!$ character(*), parameter :: subname = 'DCDateTimeEval0'
951!!$continue
952!!$ call BeginSub(subname)
953!!$ sec = time%sec
954!!$ if (time % caltype == CAL_CYCLIC) then
955!!$ day = modulo(dble(time%day - 1), CYCLIC_MDAYS) + 1
956!!$ mon = (time%day - 1) / CYCLIC_MDAYS
957!!$ goto 999
958!!$ endif
959!!$ if (time % caltype == CAL_NOLEAP) then
960!!$ day = modulo(time%day - 91, 365)
961!!$ year = (time%day - 91 - day) / 365
962!!$ else
963!!$ if (time % caltype == CAL_JULIAN .or. time%day < 640196) then
964!!$ day = modulo(time%day - 92, FOUR_YEARS)
965!!$ year = (time%day - 92 - day) / FOUR_YEARS * 4
966!!$ else
967!!$ day = modulo(time%day - 94, FOUR_CENTURY)
968!!$ year = (time%day - 94 - day) / FOUR_CENTURY * 400
969!!$ if (day == FOUR_CENTURY - 1) then
970!!$ year = year + 300
971!!$ day = 36525
972!!$ else
973!!$ year = year + day / 36524 * 100
974!!$ day = modulo(day, 36524)
975!!$ endif
976!!$ year = year + day / FOUR_YEARS * 4
977!!$ day = modulo(day, FOUR_YEARS)
978!!$ endif
979!!$ if (day == FOUR_YEARS - 1) then
980!!$ year = year + 3
981!!$ day = 365
982!!$ else
983!!$ year = year + day / 365
984!!$ day = modulo(day, 365)
985!!$ endif
986!!$ endif
987!!$ day = day * 10 + 922
988!!$ month = day / 306
989!!$ mon = mod(month - 1, 12) + 1
990!!$ year = year + (month - mon) / 12
991!!$ day = mod(day, 306) / 10 + 1
992!!$999 continue
993!!$ call EndSub(subname, 'mon=<%d>, day=<%d>, sec=<%f>',&
994!!$ & i=(/mon, day/), d=(/sec/))
995!!$end subroutine DCDateTimeEval0
subroutine dcdifftimeeval1(diff, year, mon, day, hour, min, sec, nondim, sclyear, sclmon, sclday, sclsec, sclnondim, err)
type(dc_scaled_sec) function dcdifftimeevalsclsec(diff)
real(dp) function dcdifftimeevalbyunit(diff, unit, unit_symbol)
real(dp) function dcdatetimeevalhour(time)
subroutine dcdatetimeeval1(time, year, mon, day, hour, min, sec, caltype, zone, sclyear, sclmon, sclday, sclsec)
real(dp) function dcdatetimeevalsec(time)
real(dp) function dcdifftimeevalnondim(diff)
real(dp) function dcdatetimeevalday(time)
real(dp) function dcdatetimeevalbyunit(time, unit, unit_symbol)
real(dp) function dcdifftimeevalhour(diff)
real(dp) function dcdifftimeevalmin(diff)
real(dp) function dcdatetimeevalmin(time)
type(dc_scaled_sec) function dcdatetimeevalsclsec(time)
real(dp) function dcdifftimeevalday(diff)
real(dp) function dcdifftimeevalsec(diff)
dc_date より提供される手続の引用仕様宣言
日付・時刻に関する構造データ型と定数
integer, parameter, public unit_symbol_err
無効な単位を示すシンボル
integer, parameter, public unit_symbol_hour
時間の単位を示すシンボル
integer, parameter, public unit_symbol_min
分の単位を示すシンボル
integer, parameter, public cal_noleap
閏年無しの暦 (1年 365 日)
real(dp), parameter, public cyclic_mdays
周期暦での1ヶ月の日数 (DC_DIFFTIME の月換算にも使用)
integer, parameter, public hour_seconds
1時間の秒数
integer, parameter, public four_years
4年の日数 (閏年を含む)
integer, parameter, public cal_cyclic
周期暦 (1ヶ月 30.6 日)
real(dp), save, public day_seconds
1日の秒数 (可変, デフォルトは地球の1日)
integer, parameter, public unit_symbol_sec
秒の単位を示すシンボル
integer, parameter, public unit_symbol_nondim
無次元時間の単位を示すシンボル
integer, parameter, public year_days
1年 (非閏年) の日数
integer, parameter, public year_months
1年の月数
integer, parameter, public four_century
400年の日数
integer, parameter, public min_seconds
1分の秒数
integer, parameter, public unit_symbol_day
日の単位を示すシンボル
integer, parameter, public cal_julian
ユリウス暦
エラー処理用モジュール
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_enodimtime
Definition dc_error.f90:549
integer, parameter, public dc_noerr
エラー等を保持
Definition dc_error.f90:468
integer, parameter, public dc_edimtime
Definition dc_error.f90:550
精密な時間演算のための秒スケールモジュール
subroutine, public dcscaledsecputline(sclsec, unit, indent)
デバッグ時の追跡用モジュール
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:457
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:580
種別型パラメタを提供します。
Definition dc_types.f90:55
integer, parameter, public dp
倍精度実数型変数
Definition dc_types.f90:92