gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dcdatetimecreate.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!-----------------------------------------------------------------------
5!>
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 Create DC_DATETIME and DC_DIFFTIME type variables
11!> @details
12!> Procedures described in this file are provided from "dc_date" module.
13!> @enden
14!>
15!> @ja
16!> @brief dc_date_types#DC_DATETIME, dc_date_types#DC_DIFFTIME 型変数の生成
17!> @details
18!> このファイルで提供される手続き群は dc_date モジュールにて提供されます.
19!> @endja
20!>
21
22!> @en
23!> @brief Create DC_DATETIME type variable
24!> @details
25!> Create dc_date_types#DC_DATETIME type variable.
26!> If all arguments `year`, `mon`, `day`, `hour`, `min`, `sec` are not given,
27!> the current time is used.
28!>
29!> Set calendar type with `caltype` argument.
30!> Use one of dc_date_types#CAL_CYCLIC, dc_date_types#CAL_NOLEAP,
31!> dc_date_types#CAL_JULIAN, dc_date_types#CAL_GREGORIAN.
32!> If `caltype` is not specified, calendar is set to dc_date_types#CAL_GREGORIAN.
33!> Calendar can also be specified by string with `caltype_str`.
34!> Corresponding strings (case insensitive) are:
35!>
36!> | caltype | caltype_str |
37!> |------------------------------|-------------|
38!> | dc_date_types#CAL_CYCLIC | cyclic |
39!> | dc_date_types#CAL_NOLEAP | noleap |
40!> | dc_date_types#CAL_JULIAN | julian |
41!> | dc_date_types#CAL_GREGORIAN | gregorian |
42!>
43!> Set timezone from UTC with `zone` argument.
44!> Specify timezone as 6 characters like '+09:00' or '-13:00'.
45!> If `zone` is not specified, timezone obtained from date_and_time
46!> intrinsic subroutine is used.
47!> Timezone can also be specified with `zone_hour` or `zone_min` as integer.
48!>
49!> Set seconds per day with `day_seconds` argument.
50!> If not specified, dc_date_types#day_seconds value is used.
51!> dc_date_types#day_seconds can be changed with SetSecOfDay.
52!>
53!> If invalid value is given to `caltype` or `zone`, an error occurs.
54!> If `err` argument is given, `.true.` is returned to `err` and
55!> the program continues.
56!>
57!> @param[out] time Created DC_DATETIME variable
58!> @param[in] year Year
59!> @param[in] mon Month
60!> @param[in] day Day
61!> @param[in] hour Hour
62!> @param[in] min Minute
63!> @param[in] sec Second
64!> @param[in] zone Timezone from UTC
65!> @param[in] zone_hour Timezone (hour)
66!> @param[in] zone_min Timezone (minute)
67!> @param[in] caltype Calendar type
68!> @param[in] caltype_str Calendar type (string)
69!> @param[in] day_seconds Seconds per day
70!> @param[in] sclyear Year (DC_SCALED_SEC type)
71!> @param[in] sclmon Month (DC_SCALED_SEC type)
72!> @param[in] sclday Day (DC_SCALED_SEC type)
73!> @param[in] sclsec Second (DC_SCALED_SEC type)
74!> @param[out] err Exception handling flag
75!> @enden
76!>
77!> @ja
78!> @brief DC_DATETIME 型変数を生成
79!> @details
80!> dc_date_types#DC_DATETIME 型変数の生成を行います.
81!> 引数 `year`, `mon`, `day`, `hour`, `min`, `sec` の全てを与えない場合,
82!> このサブルーチンが呼ばれた際の時刻が使用されます.
83!>
84!> 引数 `caltype` には暦法を設定します.
85!> dc_date_types#CAL_CYCLIC, dc_date_types#CAL_NOLEAP,
86!> dc_date_types#CAL_JULIAN, dc_date_types#CAL_GREGORIAN
87!> のいづれかを与えてください. 引数 `caltype` を指定しない場合, 暦法は
88!> dc_date_types#CAL_GREGORIAN に設定されます.
89!> 暦法は `caltype_str` に文字列を与えることでも指定可能です.
90!> 上記の暦法に対応する文字列は以下の通りです. (大文字小文字は区別しません)
91!>
92!> | caltype | caltype_str |
93!> |------------------------------|-------------|
94!> | dc_date_types#CAL_CYCLIC | cyclic |
95!> | dc_date_types#CAL_NOLEAP | noleap |
96!> | dc_date_types#CAL_JULIAN | julian |
97!> | dc_date_types#CAL_GREGORIAN | gregorian |
98!>
99!> 引数 `zone` には UTC からの時差を設定します.
100!> '+09:00' や '-13:00' のように時差を 6 文字で指定してください.
101!> 引数 `zone` を指定しない場合, date_and_time 組み込みサブルーチン
102!> によって得られる時差を設定します.
103!> 時差は `zone_hour` または `zone_min` に整数型を与えることでも
104!> 指定可能です.
105!>
106!> 引数 `day_seconds` には 1 日何秒かを設定します. この引数を
107!> 指定しない場合, dc_date_types#day_seconds の値が用いられます.
108!> dc_date_types#day_seconds は SetSecOfDay で変更可能です.
109!>
110!> 引数 `caltype` および, `zone` に不適切な値が与えられた場合,
111!> エラーを発生させます.
112!> 引数 `err` を与えている場合には `err` に .true. が返り,
113!> プログラムは続行します.
114!>
115!> @param[out] time 生成される DC_DATETIME 変数
116!> @param[in] year 年
117!> @param[in] mon 月
118!> @param[in] day 日
119!> @param[in] hour 時
120!> @param[in] min 分
121!> @param[in] sec 秒
122!> @param[in] zone UTC からの時差
123!> @param[in] zone_hour UTC からの時差 (時)
124!> @param[in] zone_min UTC からの時差 (分)
125!> @param[in] caltype 暦法
126!> @param[in] caltype_str 暦法 (文字型による指定)
127!> @param[in] day_seconds 1 日の秒数
128!> @param[in] sclyear 年 (DC_SCALED_SEC 型)
129!> @param[in] sclmon 月 (DC_SCALED_SEC 型)
130!> @param[in] sclday 日 (DC_SCALED_SEC 型)
131!> @param[in] sclsec 秒 (DC_SCALED_SEC 型)
132!> @param[out] err 例外処理用フラグ
133!> @endja
134subroutine dcdatetimecreate1(time, &
135 & year, mon, day, hour, min, sec, &
136 & zone, zone_hour, zone_min, caltype, caltype_str, day_seconds, &
137 & sclyear, sclmon, sclday, sclsec, err)
138
143 & caltype_default => caltype, &
148 use dc_message, only: messagenotify
149 use dc_trace, only: beginsub, endsub
150 use dc_present, only: present_select
151 use dc_string, only: lchar, cprintf
152 use dc_scaledsec, only: dc_scaled_sec, &
153 & assignment(=), dcscaledsecputline, &
154 & operator(==), operator(>), operator(<), operator(>=), operator(<=), &
155 & operator(+), operator(-), operator(*), operator(/), mod, modulo, &
157 use dc_types, only: dp, string
158 implicit none
159 type(dc_datetime), intent(out) :: time
160 integer, intent(in), optional:: year
161 integer, intent(in), optional:: mon
162 integer, intent(in), optional:: day
163 integer, intent(in), optional:: hour
164 integer, intent(in), optional:: min
165 real(DP),intent(in), optional:: sec
166 character(*), intent(in), optional :: zone
167 integer, intent(in), optional :: zone_hour
168 integer, intent(in), optional :: zone_min
169 integer, intent(in), optional:: caltype
170 character(*), intent(in), optional:: caltype_str
171 real(DP),intent(in), optional:: day_seconds
172 type(dc_scaled_sec), intent(in), optional:: sclyear
173 type(dc_scaled_sec), intent(in), optional:: sclmon
174 type(dc_scaled_sec), intent(in), optional:: sclday
175 type(dc_scaled_sec), intent(in), optional:: sclsec
176 logical, intent(out), optional:: err
177
178 real(DP):: gcsec
179 integer :: gcday, gcmon, gcyear
180 real(DP):: essec, esds
181 integer :: esday
182 type(dc_scaled_sec):: iday, imon, month, iyear, century, isec
183 character(6) :: izone
184 integer, parameter:: year_default = 0, mon_default = 1
185 integer, parameter:: day_default = 1
186 integer, parameter:: sec_default = 0
187 logical :: current_time_used
188 type(dc_difftime):: zonediff
189 character(STRING):: zone_str_long
190 integer :: stat, cause_i
191 character(STRING) :: cause_c
192 character(*), parameter :: subname = 'DCDateTimeCreate1'
193continue
194 current_time_used = .not. present(year) &
195 & .and. .not. present(mon) &
196 & .and. .not. present(day) &
197 & .and. .not. present(hour) &
198 & .and. .not. present(min) &
199 & .and. .not. present(sec) &
200 & .and. .not. present(sclyear) &
201 & .and. .not. present(sclmon) &
202 & .and. .not. present(sclday) &
203 & .and. .not. present(sclsec)
204 call beginsub(subname, 'current_time_used=<%y>', l=(/current_time_used/))
205 stat = dc_noerr
206 cause_i = dc_noerr
207 cause_c = ''
208
209 if ( present(day_seconds) ) then
210 time % day_seconds = day_seconds
211 else
213 time % day_seconds = day_seconds_scl
214 end if
215
216 call get_current_time(gcyear, gcmon, gcday, gcsec, izone) ! (out)
217 iyear = gcyear
218 imon = gcmon
219 iday = gcday
220 isec = gcsec
221
222 if (.not. current_time_used) then
223 if ( present(zone_hour) .or. present(zone_min) ) then
224 call dcdifftimecreate( zonediff, & ! (out)
225 & hour = zone_hour, min = zone_min ) ! (in)
226 zone_str_long = tochar(zonediff)
227 if ( zone_str_long(1:1) == '-' ) then
228 izone(1:1) = '-'
229 else
230 izone(1:1) = '+'
231 end if
232 izone(2:6) = zone_str_long(13:17)
233 end if
234 if (present(zone)) then
235 izone = zone
236 end if
237 if ( .not. validzone(izone)) then
238 stat = dc_ebadtimezone
239 cause_c = izone
240 if (present(err)) then
241 call messagenotify('W', subname, &
242 & 'zone=<%c> is invalid.', &
243 & c1=trim(izone))
244 else
245 goto 999
246 end if
247 end if
248
249 if ( present(sclsec) ) then
250 isec = sclsec
251 elseif( present(sec) ) then
252 isec = sec
253 else
254 isec = sec_default
255 end if
256 if (present(min)) then
257 isec = isec + min * min_seconds
258 end if
259 if (present(hour)) then
260 isec = isec + hour * hour_seconds
261 end if
262
263 if ( present(sclday) ) then
264 iday = sclday
265 elseif( present(day) ) then
266 iday = day
267 else
268 iday = day_default
269 end if
270
271 if ( present(sclday) ) then
272 iday = sclday
273 elseif( present(day) ) then
274 iday = day
275 else
276 iday = day_default
277 end if
278 iday = iday + floor(isec / time % day_seconds)
279
280 if ( present(sclmon) ) then
281 imon = sclmon
282 elseif( present(mon) ) then
283 imon = mon
284 else
285 imon = mon_default
286 end if
287
288 if ( present(sclyear) ) then
289 iyear = sclyear
290 elseif( present(year) ) then
291 iyear = year
292 else
293 iyear = year_default
294 end if
295 end if
296
297 time % zone = izone
298 time % sec = modulo(isec, time % day_seconds)
299 time % caltype = caltype_default
300 if (present(caltype_str)) then
301 select case( lchar(trim(caltype_str)) )
302 case('cyclic')
303 time % caltype = cal_cyclic
304 case('noleap')
305 time % caltype = cal_noleap
306 case('julian')
307 time % caltype = cal_julian
308 case('gregorian')
309 time % caltype = cal_gregorian
310 case('')
311 time % caltype = cal_gregorian
312 case default
313 stat = dc_ebadcaltype
314 cause_i = 0
315 call messagenotify('W', subname, &
316 & 'caltype=<%c> is invalid calender type.', &
317 & c1 = trim(caltype_str) )
318 if ( .not. present(err) ) then
319 goto 999
320 end if
321 end select
322 end if
323
324 if (present(caltype)) then
325 if (validcaltype(caltype)) then
326 time % caltype = caltype
327 else
328 stat = dc_ebadcaltype
329 cause_i = caltype
330 if (present(err)) then
331 call messagenotify('W', subname, &
332 & 'caltype=<%d> is invalid calender type.', &
333 & i=(/caltype/))
334 else
335 goto 999
336 end if
337 end if
338 end if
339 if (time % caltype == cal_cyclic) then
340 time % day = int( iday + imon * cyclic_mdays )
341 goto 999
342 endif
343 month = modulo(imon - 3, year_months) + 3
344 iyear = iyear + int( (imon - month) / year_months )
345 iday = iday + int( (month * 306 - 914) / 10 )
346 if (time % caltype == cal_noleap) then
347 time % day = iday + iyear * 365 + 90
348 else
349 iday = iday + int( (iyear * four_years - modulo(iyear * four_years, 4)) / 4 )
350 if (time % caltype == cal_julian) then
351 time % day = iday + 91
352 elseif (iday < 640116) then
353 time % day = iday + 91
354 else
355 century = (iyear - modulo(iyear, 100)) / 100 + 1
356 time % day = iday - int( (century * 3 - modulo(century * 3, 4)) / 4 ) + 93
357 endif
358 endif
359
360
361999 continue
362 call storeerror(stat, subname, err, cause_c, cause_i)
363 esday = time % day ; essec = time % sec ; esds = time % day_seconds
364 call endsub(subname, 'time (caltype=%d, day=%d, sec=%f, zone=%c, day_seconds=%f)', &
365 & i=(/time % caltype, esday/), d=(/essec, esds/), &
366 & c1=trim(time % zone))
367
368 contains
369 !> @en
370 !> @brief Get current time using date_and_time intrinsic subroutine
371 !> @details
372 !> Returns current time and timezone from UTC using date_and_time intrinsic subroutine.
373 !> @param[out] jyear Year
374 !> @param[out] jmon Month
375 !> @param[out] jday Day
376 !> @param[out] jsec Second
377 !> @param[out] jzone Timezone
378 !> @enden
379 !>
380 !> @ja
381 !> @brief date_and_time 組み込みサブルーチンを用いて現在時刻を取得
382 !> @details
383 !> date_and_time 組み込みサブルーチンを用いて, 現在
384 !> 時刻と UTC からの時差を返します.
385 !> @param[out] jyear 年
386 !> @param[out] jmon 月
387 !> @param[out] jday 日
388 !> @param[out] jsec 秒
389 !> @param[out] jzone タイムゾーン
390 !> @endja
391 subroutine get_current_time(jyear, jmon, jday, jsec, jzone)
392 use dc_types, only: dp
393 use dc_string, only: stod
394 implicit none
395 integer, intent(out) :: jyear, jmon, jday
396 real(DP), intent(out) :: jsec
397 character(*), intent(out) :: jzone
398
399 integer :: date_time_values(1:8)
400 character(5) :: zone_raw
401 continue
402
403 call date_and_time(zone=zone_raw, values=date_time_values)
404
405 jzone = zone_raw(1:3) // ":" // zone_raw(4:5)
406
407 jyear = date_time_values(1)
408 jmon = date_time_values(2)
409 jday = date_time_values(3)
410 jsec = real(date_time_values(5), dp) * hour_seconds &
411 & + real(date_time_values(6), dp) * min_seconds &
412 & + real(date_time_values(7), dp)
413
414 end subroutine get_current_time
415
416end subroutine dcdatetimecreate1
417
418
419!> @en
420!> @brief Create DC_DIFFTIME type variable
421!> @details
422!> Create dc_date_types#DC_DIFFTIME type variable.
423!> If arguments `year`, `mon`, `day`, `hour`, `min`, `sec`, `nondim` are not given,
424!> 0 is used.
425!>
426!> Set seconds per day with `day_seconds` argument.
427!> If not specified, dc_date_types#day_seconds value is used.
428!> dc_date_types#day_seconds can be changed with SetSecOfDay.
429!>
430!> @param[out] diff Created DC_DIFFTIME variable
431!> @param[in] year Year
432!> @param[in] mon Month
433!> @param[in] day Day
434!> @param[in] hour Hour
435!> @param[in] min Minute
436!> @param[in] sec Second
437!> @param[in] day_seconds Seconds per day
438!> @param[in] nondim Nondimensional time
439!> @param[in] sclyear Year (DC_SCALED_SEC type)
440!> @param[in] sclmon Month (DC_SCALED_SEC type)
441!> @param[in] sclday Day (DC_SCALED_SEC type)
442!> @param[in] sclsec Second (DC_SCALED_SEC type)
443!> @enden
444!>
445!> @ja
446!> @brief DC_DIFFTIME 型変数を生成
447!> @details
448!> dc_date_types#DC_DIFFTIME 型変数の生成を行います.
449!> 引数 `year`, `mon`, `day`, `hour`, `min`, `sec`, `nondim` を与えない場合,
450!> 0 が与えられたことになります.
451!>
452!> 引数 `day_seconds` には 1 日何秒かを設定します. この引数を
453!> 指定しない場合, dc_date_types#day_seconds の値が用いられます.
454!> dc_date_types#day_seconds は SetSecOfDay で変更可能です.
455!>
456!> @param[out] diff 生成される DC_DIFFTIME 変数
457!> @param[in] year 年
458!> @param[in] mon 月
459!> @param[in] day 日
460!> @param[in] hour 時
461!> @param[in] min 分
462!> @param[in] sec 秒
463!> @param[in] day_seconds 1 日の秒数
464!> @param[in] nondim 無次元時間
465!> @param[in] sclyear 年 (DC_SCALED_SEC 型)
466!> @param[in] sclmon 月 (DC_SCALED_SEC 型)
467!> @param[in] sclday 日 (DC_SCALED_SEC 型)
468!> @param[in] sclsec 秒 (DC_SCALED_SEC 型)
469!> @endja
470subroutine dcdifftimecreate1(diff, &
471 & year, mon, day, hour, min, sec, day_seconds, nondim, &
472 & sclyear, sclmon, sclday, sclsec )
475 use dc_date_types, only: dc_difftime, &
476 & day_seconds_default => day_seconds, &
478 use dc_message, only: messagenotify
479 use dc_trace, only: beginsub, endsub, debug
480 use dc_present, only: present_select
481 use dc_scaledsec, only: dc_scaled_sec, &
482 & assignment(=), dcscaledsecputline, &
483 & operator(==), operator(>), operator(<), operator(>=), operator(<=), &
484 & operator(+), operator(-), operator(*), operator(/), mod, modulo, &
485 & abs, int, sign, floor
486 use dc_string, only: cprintf
487 use dc_types, only: dp, string
488 implicit none
489 type(dc_difftime), intent(out) :: diff
490 integer, intent(in), optional:: year
491 integer, intent(in), optional:: mon
492 integer, intent(in), optional:: day
493 integer, intent(in), optional:: hour
494 integer, intent(in), optional:: min
495 real(DP), intent(in), optional:: sec
496 real(DP), intent(in), optional:: day_seconds
497 real(DP), intent(in), optional:: nondim
498 type(dc_scaled_sec), intent(in), optional:: sclyear
499 type(dc_scaled_sec), intent(in), optional:: sclmon
500 type(dc_scaled_sec), intent(in), optional:: sclday
501 type(dc_scaled_sec), intent(in), optional:: sclsec
502
503 type(dc_scaled_sec):: iyear, imon, iday, ihour, imin, isec
504 integer, parameter:: year_default = 0, mon_default = 0
505 integer, parameter:: day_default = 0, hour_default = 0, min_default = 0
506 integer, parameter:: sec_default = 0
507 real(DP):: essec, esds
508 integer :: esmon, esday
509 character(STRING):: endsub_msb
510 logical:: dbg_mode
511 character(*), parameter :: subname = 'DCDiffTimeCreate1'
512continue
513 call beginsub(subname)
514
515 if ( present(nondim) ) then
516 diff % nondim_flag = .true.
517 diff % mon = 0
518 diff % day = 0
519 diff % sec = nondim
520 goto 999
521 else
522 diff % nondim_flag = .false.
523 end if
524
525 if ( present(sclyear) ) then
526 iyear = sclyear
527 elseif( present(year) ) then
528 iyear = year
529 else
530 iyear = year_default
531 end if
532
533 if ( present(sclmon) ) then
534 imon = sclmon
535 elseif( present(mon) ) then
536 imon = mon
537 else
538 imon = mon_default
539 end if
540
541 if ( present(sclday) ) then
542 iday = sclday
543 elseif( present(day) ) then
544 iday = day
545 else
546 iday = day_default
547 end if
548
549 ihour = present_select(.false., hour_default, hour)
550 imin = present_select(.false., min_default, min)
551
552 if ( present(sclsec) ) then
553 isec = sclsec
554 elseif( present(sec) ) then
555 isec = sec
556 else
557 isec = sec_default
558 end if
559
560 diff % mon = iyear * year_months + imon
561 diff % day = iday
562 diff % sec = ihour * hour_seconds &
563 & + imin * min_seconds &
564 & + isec
565
566 if( present(day_seconds) ) then
567 diff % day_seconds = day_seconds
568 else
569 diff % day_seconds = day_seconds_default
570 end if
571
572 call dcdate_normalize(diff % day, diff % sec, diff % day_seconds, diff % nondim_flag)
573
574999 continue
575 call debug( dbg_mode )
576 if ( dbg_mode ) then
577 esmon = diff % mon ; esday = diff % day
578 essec = diff % sec ; esds = diff % day_seconds
579 endsub_msb = &
580 & cprintf( 'mon=%d, day=%d, sec=%f, day_seconds=%f, nondim_flag=%b', &
581 & i = (/ esmon, esday /), d = (/ essec, esds /), &
582 & l = (/ diff % nondim_flag /) )
583 else
584 endsub_msb = ''
585 end if
586 call endsub(subname, 'diff (%c)', c1 = trim(endsub_msb) )
587end subroutine dcdifftimecreate1
588
589
590!> @en
591!> @brief Create DC_DIFFTIME type variable with value and unit
592!> @details
593!> Create dc_date_types#DC_DIFFTIME type variable.
594!> Specify value with `value` argument and unit with `unit` string
595!> or unit symbol with `unit_symbol`.
596!>
597!> Valid strings for `unit` (case insensitive):
598!>
599!> | Unit | String |
600!> |---------------|------------------------------|
601!> | Year | dc_date_types#UNIT_YEAR |
602!> | Month | dc_date_types#UNIT_MONTH |
603!> | Day | dc_date_types#UNIT_DAY |
604!> | Hour | dc_date_types#UNIT_HOUR |
605!> | Minute | dc_date_types#UNIT_MIN |
606!> | Second | dc_date_types#UNIT_SEC |
607!> | Nondimensional| dc_date_types#UNIT_NONDIM |
608!>
609!> If invalid string is given to `unit`, an error occurs.
610!>
611!> Valid symbols for `unit_symbol`:
612!>
613!> | Unit | Symbol |
614!> |---------------|-------------------------------------|
615!> | Year | dc_date_types#UNIT_SYMBOL_YEAR |
616!> | Month | dc_date_types#UNIT_SYMBOL_MONTH |
617!> | Day | dc_date_types#UNIT_SYMBOL_DAY |
618!> | Hour | dc_date_types#UNIT_SYMBOL_HOUR |
619!> | Minute | dc_date_types#UNIT_SYMBOL_MIN |
620!> | Second | dc_date_types#UNIT_SYMBOL_SEC |
621!> | Nondimensional| dc_date_types#UNIT_SYMBOL_NONDIM |
622!>
623!> If invalid symbol is given to `unit_symbol`, an error occurs.
624!> If `err` argument is given, `.true.` is returned to `err` and
625!> the program continues.
626!>
627!> @param[out] diff Created DC_DIFFTIME variable
628!> @param[in] value Value
629!> @param[in] unit Unit string
630!> @param[in] unit_symbol Unit symbol
631!> @param[out] err Exception handling flag
632!> @enden
633!>
634!> @ja
635!> @brief 値と単位から DC_DIFFTIME 型変数を生成
636!> @details
637!> dc_date_types#DC_DIFFTIME 型変数の生成を行います.
638!> 引数 `value` に数値を, `unit` に単位を表す文字列を,
639!> または `unit_symbol` に単位を表すシンボルを与えてください.
640!>
641!> `unit` に指定できるのは以下の文字列です. (大文字小文字は区別しません).
642!>
643!> | 単位 | 文字列 |
644!> |------------|------------------------------|
645!> | 年 | dc_date_types#UNIT_YEAR |
646!> | 月 | dc_date_types#UNIT_MONTH |
647!> | 日 | dc_date_types#UNIT_DAY |
648!> | 時 | dc_date_types#UNIT_HOUR |
649!> | 分 | dc_date_types#UNIT_MIN |
650!> | 秒 | dc_date_types#UNIT_SEC |
651!> | 無次元時間 | dc_date_types#UNIT_NONDIM |
652!>
653!> これらに該当しない文字列を `unit` に与えた場合, エラーを発生させます.
654!>
655!> `unit_symbol` に指定できるのは以下のシンボルです.
656!>
657!> | 単位 | シンボル |
658!> |------------|-------------------------------------|
659!> | 年 | dc_date_types#UNIT_SYMBOL_YEAR |
660!> | 月 | dc_date_types#UNIT_SYMBOL_MONTH |
661!> | 日 | dc_date_types#UNIT_SYMBOL_DAY |
662!> | 時 | dc_date_types#UNIT_SYMBOL_HOUR |
663!> | 分 | dc_date_types#UNIT_SYMBOL_MIN |
664!> | 秒 | dc_date_types#UNIT_SYMBOL_SEC |
665!> | 無次元時間 | dc_date_types#UNIT_SYMBOL_NONDIM |
666!>
667!> これらに該当しないシンボルを `unit_symbol` に与えた場合,
668!> エラーを発生させます.
669!>
670!> 引数 `err` を与えている場合には `err` に .true. が返り,
671!> プログラムは続行します.
672!>
673!> @param[out] diff 生成される DC_DIFFTIME 変数
674!> @param[in] value 値
675!> @param[in] unit 単位文字列
676!> @param[in] unit_symbol 単位シンボル
677!> @param[out] err 例外処理用フラグ
678!> @endja
679subroutine dcdifftimecreate2d(diff, value, unit, unit_symbol, err)
680 use dc_types, only: dp, string
681 use dc_trace, only: beginsub, endsub
683 use dc_string, only: strieq
685 use dc_date_types, only: dc_difftime, &
688 & unit_symbol_err, &
690 use dc_scaledsec, only: dc_scaled_sec, &
691 & assignment(=), dcscaledsecputline, &
692 & operator(==), operator(>), operator(<), operator(>=), operator(<=), &
693 & operator(+), operator(-), operator(*), operator(/), mod, modulo, &
694 & abs, int, sign, floor
695 implicit none
696 type(dc_difftime), intent(out) :: diff
697 real(DP), intent(in) :: value
698 character(*), intent(in) :: unit
699 integer, intent(in), optional :: unit_symbol
700 logical, intent(out), optional :: err
701
702 real(DP):: essec
703 integer :: esmon, esday
704 integer :: stat, val_int
705 type(dc_scaled_sec):: val_scl, val_dec
706 character(STRING) :: cause_c
707 integer:: symbol
708
709 character(*), parameter :: subname = 'DCDiffTimeCreate2'
710continue
711 call beginsub(subname, 'value=%f', d=(/value/))
712 stat = dc_noerr
713 cause_c = ''
714 symbol = unit_symbol_err
715 if ( present(unit_symbol) ) then
716 symbol = unit_symbol
717 else
718 symbol = parsetimeunits(unit)
719 end if
720
721 if ( symbol == unit_symbol_sec ) then
722 call dcdifftimecreate(diff, sec=value)
723 goto 999
724 elseif ( symbol == unit_symbol_nondim ) then
725 call dcdifftimecreate(diff, nondim=value)
726 goto 999
727 end if
728
729 val_int = int(value)
730 val_scl = int(value)
731 val_dec = value - int(value)
732
733 if ( symbol == unit_symbol_min ) then
734 call dcdifftimecreate(diff, min = val_int, sclsec = val_dec * min_seconds)
735 elseif ( symbol == unit_symbol_hour ) then
736 call dcdifftimecreate(diff, hour = val_int, sclsec = val_dec * hour_seconds)
737 elseif ( symbol == unit_symbol_day ) then
738 call dcdifftimecreate(diff, sclday = val_scl, sclsec = val_dec * day_seconds)
739 elseif ( symbol == unit_symbol_month ) then
740 call dcdifftimecreate(diff, sclmon = val_scl, &
741 & sclsec = int(val_dec * cyclic_mdays) * day_seconds)
742 elseif ( symbol == unit_symbol_year ) then
743 call dcdifftimecreate(diff, sclyear = val_scl, &
744 & sclsec = int(val_dec * cyclic_mdays * year_months) * day_seconds)
745 else
746 stat = dc_ebadunit
747 cause_c = unit
748 end if
749
750999 continue
751 call storeerror(stat, subname, err, cause_c)
752 esmon = diff % mon ; esday = diff % day ; essec = diff % sec
753 call endsub(subname, 'diff (mon=%d, day=%d, sec=%f)', &
754 & i=(/esmon, esday/), d=(/essec/))
755end subroutine dcdifftimecreate2d
756
757!> @en
758!> @brief Create DC_DIFFTIME type variable with single precision value and unit
759!> @param[out] diff Created DC_DIFFTIME variable
760!> @param[in] value Value (single precision)
761!> @param[in] unit Unit string
762!> @param[in] unit_symbol Unit symbol
763!> @param[out] err Exception handling flag
764!> @enden
765!>
766!> @ja
767!> @brief 単精度値と単位から DC_DIFFTIME 型変数を生成
768!> @param[out] diff 生成される DC_DIFFTIME 変数
769!> @param[in] value 値 (単精度)
770!> @param[in] unit 単位文字列
771!> @param[in] unit_symbol 単位シンボル
772!> @param[out] err 例外処理用フラグ
773!> @endja
774subroutine dcdifftimecreate2r(diff, value, unit, unit_symbol, err)
775 use dc_types, only: dp
777 use dc_date_types, only: dc_difftime
778 implicit none
779 type(dc_difftime), intent(out) :: diff
780 real, intent(in) :: value
781 character(*), intent(in) :: unit
782 integer, intent(in), optional :: unit_symbol
783 logical, intent(out), optional :: err
784continue
785 call dcdifftimecreate(diff, real( value, dp ), unit, unit_symbol, err)
786end subroutine dcdifftimecreate2r
787
788!> @en
789!> @brief Create DC_DIFFTIME type variable with integer value and unit
790!> @param[out] diff Created DC_DIFFTIME variable
791!> @param[in] value Value (integer)
792!> @param[in] unit Unit string
793!> @param[in] unit_symbol Unit symbol
794!> @param[out] err Exception handling flag
795!> @enden
796!>
797!> @ja
798!> @brief 整数値と単位から DC_DIFFTIME 型変数を生成
799!> @param[out] diff 生成される DC_DIFFTIME 変数
800!> @param[in] value 値 (整数)
801!> @param[in] unit 単位文字列
802!> @param[in] unit_symbol 単位シンボル
803!> @param[out] err 例外処理用フラグ
804!> @endja
805subroutine dcdifftimecreate2i(diff, value, unit, unit_symbol, err)
806 use dc_types, only: dp
808 use dc_date_types, only: dc_difftime
809 implicit none
810 type(dc_difftime), intent(out) :: diff
811 integer, intent(in) :: value
812 character(*), intent(in) :: unit
813 integer, intent(in), optional :: unit_symbol
814 logical, intent(out), optional :: err
815continue
816 call dcdifftimecreate(diff, real( value, dp ), unit, unit_symbol, err)
817end subroutine dcdifftimecreate2i
818
819!> @en
820!> @brief Create DC_DATETIME type variable with integer seconds
821!> @details
822!> Create dc_date_types#DC_DATETIME type variable.
823!> Specify seconds with `sec` argument.
824!> Use Create for year/month/day/hour/minute specification.
825!>
826!> @param[out] time Created DC_DATETIME variable
827!> @param[in] sec Seconds (integer)
828!> @enden
829!>
830!> @ja
831!> @brief 整数秒数から DC_DATETIME 型変数を生成
832!> @details
833!> dc_date_types#DC_DATETIME 型変数の生成を行います.
834!> 引数 `sec` には秒数を与えてください. 年月日, 時分を使って
835!> 指定を行いたい場合は Create を利用してください.
836!>
837!> @param[out] time 生成される DC_DATETIME 変数
838!> @param[in] sec 秒数 (整数)
839!> @endja
840subroutine dcdatetimecreatei(time, sec)
841 use dc_types, only: dp
842 use dc_date_types, only: dc_datetime
844 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
845 implicit none
846 type(dc_datetime), intent(out):: time
847 integer, intent(in):: sec
848continue
849 call dcdatetimecreate(time, sec = real(sec, dp) )
850end subroutine dcdatetimecreatei
851
852!> @en
853!> @brief Create DC_DATETIME type variable with single precision seconds
854!> @details
855!> Create dc_date_types#DC_DATETIME type variable.
856!> Specify seconds with `sec` argument.
857!> Use Create for year/month/day/hour/minute specification.
858!>
859!> @param[out] time Created DC_DATETIME variable
860!> @param[in] sec Seconds (single precision)
861!> @enden
862!>
863!> @ja
864!> @brief 単精度秒数から DC_DATETIME 型変数を生成
865!> @details
866!> dc_date_types#DC_DATETIME 型変数の生成を行います.
867!> 引数 `sec` には秒数を与えてください. 年月日, 時分を使って
868!> 指定を行いたい場合は Create を利用してください.
869!>
870!> @param[out] time 生成される DC_DATETIME 変数
871!> @param[in] sec 秒数 (単精度)
872!> @endja
873subroutine dcdatetimecreater(time, sec)
874 use dc_types, only: dp
875 use dc_date_types, only: dc_datetime
877 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
878 implicit none
879 type(dc_datetime), intent(out):: time
880 real, intent(in):: sec
881continue
882 call dcdatetimecreate(time, sec = real(sec, dp) )
883end subroutine dcdatetimecreater
884
885!> @en
886!> @brief Create DC_DATETIME type variable with double precision seconds
887!> @param[out] time Created DC_DATETIME variable
888!> @param[in] sec Seconds (double precision)
889!> @enden
890!>
891!> @ja
892!> @brief 倍精度秒数から DC_DATETIME 型変数を生成
893!> @param[out] time 生成される DC_DATETIME 変数
894!> @param[in] sec 秒数 (倍精度)
895!> @endja
896subroutine dcdatetimecreated(time, sec)
897 use dc_types, only: dp
898 use dc_date_types, only: dc_datetime
900 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
901 implicit none
902 type(dc_datetime), intent(out):: time
903 real(DP), intent(in):: sec
904continue
905 call dcdatetimecreate(time, sec = sec)
906end subroutine dcdatetimecreated
907
908!> @en
909!> @brief Create DC_DIFFTIME type variable with integer seconds
910!> @details
911!> Create dc_date_types#DC_DIFFTIME type variable.
912!> Specify seconds with `sec` argument.
913!> Use Create for year/month/day/hour/minute specification.
914!>
915!> @param[out] diff Created DC_DIFFTIME variable
916!> @param[in] sec Seconds (integer)
917!> @enden
918!>
919!> @ja
920!> @brief 整数秒数から DC_DIFFTIME 型変数を生成
921!> @details
922!> dc_date_types#DC_DIFFTIME 型変数の生成を行います.
923!> 引数 `sec` には秒数を与えてください. 年月日, 時分を使って
924!> 指定を行いたい場合は Create を利用してください.
925!>
926!> @param[out] diff 生成される DC_DIFFTIME 変数
927!> @param[in] sec 秒数 (整数)
928!> @endja
929subroutine dcdifftimecreatei(diff, sec)
930 use dc_types, only: dp
931 use dc_date_types, only: dc_difftime
933 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
934 implicit none
935 type(dc_difftime), intent(out):: diff
936 integer, intent(in):: sec
937continue
938 call dcdifftimecreate(diff, sec = real(sec, dp) )
939end subroutine dcdifftimecreatei
940
941!> @en
942!> @brief Create DC_DIFFTIME type variable with single precision seconds
943!> @details
944!> Create dc_date_types#DC_DIFFTIME type variable.
945!> Specify seconds with `sec` argument.
946!> Use Create for year/month/day/hour/minute specification.
947!>
948!> @param[out] diff Created DC_DIFFTIME variable
949!> @param[in] sec Seconds (single precision)
950!> @enden
951!>
952!> @ja
953!> @brief 単精度秒数から DC_DIFFTIME 型変数を生成
954!> @details
955!> dc_date_types#DC_DIFFTIME 型変数の生成を行います.
956!> 引数 `sec` には秒数を与えてください. 年月日, 時分を使って
957!> 指定を行いたい場合は Create を利用してください.
958!>
959!> @param[out] diff 生成される DC_DIFFTIME 変数
960!> @param[in] sec 秒数 (単精度)
961!> @endja
962subroutine dcdifftimecreater(diff, sec)
963 use dc_types, only: dp
964 use dc_date_types, only: dc_difftime
966 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
967 implicit none
968 type(dc_difftime), intent(out):: diff
969 real, intent(in):: sec
970continue
971 call dcdifftimecreate(diff, sec = real(sec, dp) )
972end subroutine dcdifftimecreater
973
974!> @en
975!> @brief Create DC_DIFFTIME type variable with double precision seconds
976!> @param[out] diff Created DC_DIFFTIME variable
977!> @param[in] sec Seconds (double precision)
978!> @enden
979!>
980!> @ja
981!> @brief 倍精度秒数から DC_DIFFTIME 型変数を生成
982!> @param[out] diff 生成される DC_DIFFTIME 変数
983!> @param[in] sec 秒数 (倍精度)
984!> @endja
985subroutine dcdifftimecreated(diff, sec)
986 use dc_types, only: dp
987 use dc_date_types, only: dc_difftime
989 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
990 implicit none
991 type(dc_difftime), intent(out):: diff
992 real(DP), intent(in):: sec
993continue
994 call dcdifftimecreate(diff, sec = sec)
995end subroutine dcdifftimecreated
996
997
998!-----------------------------------------------
999! For backward compatibility
1000!> @en
1001!> @brief Create DC_DATETIME (backward compatibility)
1002!> @enden
1003!> @ja
1004!> @brief DC_DATETIME 生成 (後方互換用)
1005!> @endja
1006subroutine dcdatetimecreate1_bc(time, &
1007 & year, mon, day, hour, min, sec, &
1008 & zone, caltype, day_seconds, err)
1009 use dc_types, only: dp
1010 use dc_date_types, only: dc_datetime
1012 type(dc_datetime), intent(out):: time
1013 integer, intent(in), optional:: year, mon, day, hour, min
1014 real(DP),intent(in), optional:: sec, day_seconds
1015 character(*), intent(in), optional :: zone
1016 integer, intent(in), optional:: caltype
1017 logical, intent(out), optional:: err
1018continue
1019 call dcdatetimecreate( time, &
1020 & year, mon, day, hour, min, sec, &
1021 & zone, caltype, day_seconds = day_seconds, err = err )
1022end subroutine dcdatetimecreate1_bc
1023
1024!> @en
1025!> @brief Create DC_DIFFTIME (backward compatibility)
1026!> @enden
1027!> @ja
1028!> @brief DC_DIFFTIME 生成 (後方互換用)
1029!> @endja
1030subroutine dcdifftimecreate1_bc(diff, &
1031 & year, mon, day, hour, min, sec, day_seconds)
1032 use dc_types, only: dp
1033 use dc_date_types, only: dc_difftime
1035 type(dc_difftime), intent(out) :: diff
1036 integer, intent(in), optional:: year, mon, day, hour, min
1037 real(DP),intent(in), optional:: sec, day_seconds
1038continue
1039 call dcdifftimecreate( diff, &
1040 & year, mon, day, hour, min, sec, day_seconds )
1041end subroutine dcdifftimecreate1_bc
1042
1043!> @en
1044!> @brief Create DC_DIFFTIME with value and unit (backward compatibility)
1045!> @enden
1046!> @ja
1047!> @brief 値と単位から DC_DIFFTIME 生成 (後方互換用)
1048!> @endja
1049subroutine dcdifftimecreate2_bc(diff, value, unit, err)
1050 use dc_types, only: dp
1051 use dc_date_types, only: dc_difftime
1053 type(dc_difftime), intent(out) :: diff
1054 real(DP), intent(in) :: value
1055 character(*), intent(in) :: unit
1056 logical, intent(out), optional :: err
1057continue
1058 call dcdifftimecreate( diff, value, unit, err = err )
1059end subroutine dcdifftimecreate2_bc
subroutine dcdatetimecreater(time, sec)
subroutine dcdatetimecreate1_bc(time, year, mon, day, hour, min, sec, zone, caltype, day_seconds, err)
subroutine dcdifftimecreated(diff, sec)
subroutine dcdifftimecreate2r(diff, value, unit, unit_symbol, err)
subroutine dcdifftimecreatei(diff, sec)
subroutine dcdifftimecreate2d(diff, value, unit, unit_symbol, err)
subroutine dcdifftimecreater(diff, sec)
subroutine dcdifftimecreate1_bc(diff, year, mon, day, hour, min, sec, day_seconds)
subroutine dcdatetimecreatei(time, sec)
subroutine dcdatetimecreate1(time, year, mon, day, hour, min, sec, zone, zone_hour, zone_min, caltype, caltype_str, day_seconds, sclyear, sclmon, sclday, sclsec, err)
Create DC_DATETIME and DC_DIFFTIME type variables.
subroutine dcdatetimecreated(time, sec)
subroutine dcdifftimecreate2i(diff, value, unit, unit_symbol, err)
subroutine dcdifftimecreate2_bc(diff, value, unit, err)
subroutine get_current_time(jyear, jmon, jday, jsec, jzone)
subroutine dcdifftimecreate1(diff, year, mon, day, hour, min, sec, day_seconds, nondim, sclyear, sclmon, sclday, sclsec)
Interface declarations for procedures provided from dc_date.
Internal module for dc_date.
subroutine, public dcdate_set_day_seconds_scl
subroutine, public dcdate_normalize(day, sec, day_seconds, nondim_flag)
Derived types and parameters for date and time.
integer, parameter, public unit_symbol_err
Symbol for invalid unit
integer, parameter, public unit_symbol_hour
Symbol for hour unit
integer, parameter, public unit_symbol_min
Symbol for minute unit
integer, parameter, public cal_noleap
Calendar without leap years (365 days per year)
real(dp), parameter, public cyclic_mdays
Days per month for cyclic calendar (also used for DC_DIFFTIME)
integer, parameter, public hour_seconds
Seconds per hour
integer, parameter, public unit_symbol_month
Symbol for month unit
integer, parameter, public four_years
Days in 4 years (including leap year)
integer, parameter, public cal_cyclic
Cyclic calendar (30.6 days per month)
real(dp), save, public day_seconds
Seconds per day (variable, default is Earth day)
integer, save, public caltype
Default calendar type (Gregorian)
integer, parameter, public unit_symbol_sec
Symbol for second unit
integer, parameter, public unit_symbol_nondim
Symbol for nondimensional unit
type(dc_scaled_sec), save, public day_seconds_scl
Seconds per day (DC_SCALED_SEC type)
logical, save, public flag_set_day_seconds_scl
Flag indicating if day_seconds_scl is set
integer, parameter, public year_months
Months per year
integer, parameter, public cal_gregorian
Gregorian calendar
integer, parameter, public min_seconds
Seconds per minute
integer, parameter, public unit_symbol_day
Symbol for day unit
integer, parameter, public unit_symbol_year
Symbol for year unit
integer, parameter, public cal_julian
Julian calendar
Error handling module.
Definition dc_error.f90:454
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:891
integer, parameter, public dc_ebadunit
Definition dc_error.f90:536
integer, parameter, public dc_noerr
Error storage variables
Definition dc_error.f90:468
integer, parameter, public dc_ebadcaltype
Definition dc_error.f90:537
integer, parameter, public dc_ebadtimezone
Definition dc_error.f90:538
Message output module.
Judge optional control parameters.
Scaled seconds module for precise time operations.
subroutine, public dcscaledsecputline(sclsec, unit, indent)
Handling character types.
Definition dc_string.f90:83
Debug tracing module.
Definition dc_trace.f90:150
subroutine, public beginsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca, version)
Definition dc_trace.f90:476
subroutine, public endsub(name, fmt, i, r, d, l, n, c1, c2, c3, ca)
Definition dc_trace.f90:599
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public string
Character length for string
Definition dc_types.f90:137
integer, parameter, public dp
Double Precision Real number
Definition dc_types.f90:92