gtool5 Fortran 90/95 Library 1.0.0-rc5
日本語
Loading...
Searching...
No Matches
dc_date_internal.f90
Go to the documentation of this file.
1!-----------------------------------------------------------------------
2! Copyright (c) 2000-2026 Gtool Development Group. All rights reserved.
3!-----------------------------------------------------------------------
4!>
5!> @author Yasuhiro MORIKAWA, Eizi TOYODA
6!> @copyright Copyright (C) GFD Dennou Club, 2000-2026. All rights reserved. <br/>
7!> License is BSD-2-Clause. see [COPYRIGHT](@ref COPYRIGHT) in detail
8!> @private
9!> @en
10!> @brief Internal module for dc_date
11!> @details
12!> This module provides internal constants, variables, and procedures
13!> used by the dc_date module. These are for internal use only and
14!> should not be used outside of dc_date module.
15!>
16!> @section dcdate_internal_procedures Internal procedures
17!>
18!> | Procedure | Description |
19!> |-------------------------|------------------------------------------|
20!> | dcdate_normalize | Normalize day and seconds |
21!> | dcdate_set_day_seconds_scl | Set scaled seconds for day |
22!> | dcdate_nondimcheck | Check dimensionality consistency |
23!> | dcdate_parse_unit | Parse time unit string |
24!>
25!> @enden
26!>
27!> @ja
28!> @brief dc_date用の内部モジュール
29!> @details
30!> dc_date モジュール内で使用される内部向け定数, 変数, 手続き群を
31!> 提供します. これらは内部使用専用であり, dc_date モジュール外では
32!> 極力使用しないでください.
33!>
34!> @section dcdate_internal_procedures_ja 内部手続一覧
35!>
36!> | 手続名 | 説明 |
37!> |-------------------------|------------------------------------------|
38!> | dcdate_normalize | 日と秒の正規化 |
39!> | dcdate_set_day_seconds_scl | 日のスケーリング秒数を設定 |
40!> | dcdate_nondimcheck | 次元の整合性チェック |
41!> | dcdate_parse_unit | 時間単位文字列の解析 |
42!>
43!> @endja
44!>
45
47
49 use dc_types, only: dp, string, token
51
52 implicit none
53
54 private
56 public:: dcdate_nondimcheck
57
58contains
59
60 !>
61 !> @en
62 !> @brief Normalize day and seconds
63 !> @details
64 !> Normalizes day and seconds values. If sec exceeds day_seconds,
65 !> the excess is carried over to day. Also ensures that sec and day
66 !> have the same sign.
67 !>
68 !> This is an internal subroutine and should not be used outside
69 !> of dc_date module.
70 !>
71 !> @param[in,out] day Day value
72 !> @param[in,out] sec Second value
73 !> @param[in] day_seconds Seconds in a day (optional)
74 !> @param[in] nondim_flag Non-dimensional flag
75 !> @enden
76 !>
77 !> @ja
78 !> @brief 日と秒の正規化を行います
79 !> @details
80 !> 日付 day と秒数 sec の正規化を行います. sec が day_seconds
81 !> を超える場合, day に繰上げを行います.
82 !> また, sec と day の符号が逆の場合, 同符号になるよう設定します.
83 !>
84 !> このサブルーチンは内部向けなので dc_date モジュール外では
85 !> 極力使用しないでください.
86 !>
87 !> @param[in,out] day 日
88 !> @param[in,out] sec 秒
89 !> @param[in] day_seconds 1日の秒数 (オプション)
90 !> @param[in] nondim_flag 無次元フラグ
91 !> @endja
92 !>
93 subroutine dcdate_normalize(day, sec, day_seconds, nondim_flag)
94 use dc_date_types, only: &
96 use dc_scaledsec, only: dc_scaled_sec, &
97 & operator(<), operator(>), operator(<=), operator(>=), &
98 & operator(+), operator(-), operator(*), operator(/), &
99 & modulo, int, abs, sign
100 implicit none
101 type(dc_scaled_sec), intent(inout):: day
102 type(dc_scaled_sec), intent(inout):: sec
103 type(dc_scaled_sec), intent(in), optional:: day_seconds
104 logical, intent(in):: nondim_flag
105 type(dc_scaled_sec):: sgn, day_sec, zero_sec
106 continue
107 if ( nondim_flag ) return
108 if (present(day_seconds)) then
109 day_sec = day_seconds
110 else
112 day_sec = day_seconds_scl
113 end if
114 if (abs(sec) >= day_sec) then
115 day = day + int(sec / day_sec)
116 sec = modulo(sec, day_sec)
117 end if
118!! zero_sec = 0 (デフォルト値 = 0 を使用する).
119 if ( ( sec > zero_sec .and. day < zero_sec ) &
120 & .or. ( sec < zero_sec .and. day > zero_sec ) ) then
121 sgn = sign(day, 1)
122 day = day - sgn
123 sec = sec + sgn * day_sec
124 endif
125 end subroutine dcdate_normalize
126
127 !>
128 !> @en
129 !> @brief Set scaled seconds for day
130 !> @details
131 !> Sets the scaled seconds value for day_seconds_scl.
132 !> @enden
133 !>
134 !> @ja
135 !> @brief 日のスケーリング秒数を設定します
136 !> @details
137 !> day_seconds_scl のスケーリング秒数値を設定します.
138 !> @endja
139 !>
141 use dc_scaledsec, only: dc_scaled_sec, assignment(=)
142 use dc_date_types, only: day_seconds, &
144 continue
145 if ( .not. flag_set_day_seconds_scl ) then
148 end if
149 end subroutine dcdate_set_day_seconds_scl
150
151 !>
152 !> @en
153 !> @brief Check dimensionality consistency
154 !> @details
155 !> Checks whether diff1 and diff2 are both dimensional or both
156 !> non-dimensional, and applies the result to rslt.
157 !> If one is dimensional and the other is non-dimensional,
158 !> an error is raised.
159 !>
160 !> This is an internal subroutine and should not be used outside
161 !> of dc_date module.
162 !>
163 !> @param[in] opr Name of the operator
164 !> @param[in] diff1 First operand
165 !> @param[in] diff2 Second operand
166 !> @param[inout] rslt Result operand
167 !> @enden
168 !>
169 !> @ja
170 !> @brief 次元の整合性をチェックします
171 !> @details
172 !> diff1 と diff2 が両方とも有次元もしくは無次元かをチェックし,
173 !> 両方が同じであれば, その結果を rslt に適用します.
174 !> 2つの引数で片方が有次元, もう片方が無次元の場合には
175 !> エラーを発生させます.
176 !>
177 !> このサブルーチンは内部向けなので dc_date モジュール外では
178 !> 極力使用しないでください.
179 !>
180 !> @param[in] opr 演算子の名称
181 !> @param[in] diff1 第1オペランド
182 !> @param[in] diff2 第2オペランド
183 !> @param[inout] rslt 結果オペランド
184 !> @endja
185 !>
186 subroutine dcdate_nondimcheck(opr, diff1, diff2, rslt)
188 implicit none
189 character(*), intent(in):: opr
190 type(dc_difftime), intent(in):: diff1, diff2
191 type(dc_difftime), intent(inout):: rslt
192 continue
193 if ( ( diff1 % nondim_flag .and. .not. diff2 % nondim_flag ) &
194 & .or. ( .not. diff1 % nondim_flag .and. diff2 % nondim_flag ) ) then
195 call storeerror(dc_edimtime, opr)
196 end if
197 rslt % nondim_flag = diff1 % nondim_flag
198 end subroutine dcdate_nondimcheck
199
200 !>
201 !> @en
202 !> @brief Parse time unit string and return symbol
203 !> @details
204 !> Interprets the string str and returns the time unit symbol.
205 !> The following strings are interpreted as time units (case insensitive):
206 !>
207 !> | Unit | Symbol constant |
208 !> |----------------|------------------------------|
209 !> | year | UNIT_SYMBOL_YEAR |
210 !> | month | UNIT_SYMBOL_MONTH |
211 !> | day | UNIT_SYMBOL_DAY |
212 !> | hour | UNIT_SYMBOL_HOUR |
213 !> | minute | UNIT_SYMBOL_MIN |
214 !> | second | UNIT_SYMBOL_SEC |
215 !> | non-dimensional| UNIT_SYMBOL_NONDIM |
216 !>
217 !> If str does not match any of these, UNIT_SYMBOL_ERR is returned.
218 !>
219 !> @param[in] str Input unit string
220 !> @return Unit symbol integer
221 !> @enden
222 !>
223 !> @ja
224 !> @brief 時間単位文字列を解析しシンボルを返します
225 !> @details
226 !> 引数 str に与えられた文字列を解釈し, 日時の単位を示す
227 !> シンボルを返します. 以下の文字列が日時の単位として解釈されます.
228 !> 大文字と小文字は区別されません.
229 !>
230 !> | 単位 | シンボル定数 |
231 !> |----------------|------------------------------|
232 !> | 年 | UNIT_SYMBOL_YEAR |
233 !> | 月 | UNIT_SYMBOL_MONTH |
234 !> | 日 | UNIT_SYMBOL_DAY |
235 !> | 時 | UNIT_SYMBOL_HOUR |
236 !> | 分 | UNIT_SYMBOL_MIN |
237 !> | 秒 | UNIT_SYMBOL_SEC |
238 !> | 無次元時間 | UNIT_SYMBOL_NONDIM |
239 !>
240 !> これらに該当しない文字列を str に与えた場合,
241 !> UNIT_SYMBOL_ERR が返ります.
242 !>
243 !> @param[in] str 入力単位文字列
244 !> @return 単位シンボル (整数)
245 !> @endja
246 !>
247 !>
248 !> @en
249 !> @brief Parse time unit string and return unit string
250 !> @details
251 !> Interprets the string str and returns the time unit string.
252 !> Case insensitive. Returns the first element of the unit array.
253 !> Returns empty string for unrecognized unit.
254 !>
255 !> This is an internal function and should not be used outside
256 !> of dc_date module.
257 !>
258 !> @param[in] str Input unit string
259 !> @return Standardized unit string
260 !> @enden
261 !>
262 !> @ja
263 !> @brief 時間単位文字列を解析し単位文字列を返します
264 !> @details
265 !> 引数 str に与えられた文字列を解釈し, 日時の単位を返します.
266 !> 大文字と小文字は区別されません.
267 !> 返る文字列は単位配列の先頭の文字列です.
268 !> 該当しない文字列の場合は空文字が返ります.
269 !>
270 !> この関数は内部向けなので dc_date モジュール外では
271 !> 極力使用しないでください.
272 !>
273 !> @param[in] str 入力単位文字列
274 !> @return 標準化された単位文字列
275 !> @endja
276 !>
277 character(TOKEN) function dcdate_parse_unit(str) result(unit)
278 use dc_types, only: token
281 use dc_string, only: strieq
282 implicit none
283 character(*), intent(in):: str
284 integer :: unit_str_size, i
285 continue
286 unit = adjustl(str)
287 unit_str_size = size(unit_nondim)
288 do i = 1, unit_str_size
289 if (strieq(trim(unit), trim(unit_nondim(i)))) then
290 unit = unit_nondim(1)
291 return
292 end if
293 end do
294
295 unit_str_size = size(unit_sec)
296 do i = 1, unit_str_size
297 if (strieq(trim(unit), trim(unit_sec(i)))) then
298 unit = unit_sec(1)
299 return
300 end if
301 end do
302
303 unit_str_size = size(unit_min)
304 do i = 1, unit_str_size
305 if (strieq(trim(unit), trim(unit_min(i)))) then
306 unit = unit_min(1)
307 return
308 end if
309 end do
310
311 unit_str_size = size(unit_hour)
312 do i = 1, unit_str_size
313 if (strieq(trim(unit), trim(unit_hour(i)))) then
314 unit = unit_hour(1)
315 return
316 end if
317 end do
318
319 unit_str_size = size(unit_day)
320 do i = 1, unit_str_size
321 if (strieq(trim(unit), trim(unit_day(i)))) then
322 unit = unit_day(1)
323 return
324 end if
325 end do
326
327 unit_str_size = size(unit_month)
328 do i = 1, unit_str_size
329 if (strieq(trim(unit), trim(unit_month(i)))) then
330 unit = unit_month(1)
331 return
332 end if
333 end do
334
335 unit_str_size = size(unit_year)
336 do i = 1, unit_str_size
337 if (strieq(trim(unit), trim(unit_year(i)))) then
338 unit = unit_year(1)
339 return
340 end if
341 end do
342
343 unit = ''
344
345 end function dcdate_parse_unit
346
347end module dc_date_internal
Internal module for dc_date.
character(token) function, public dcdate_parse_unit(str)
subroutine, public dcdate_set_day_seconds_scl
subroutine, public dcdate_normalize(day, sec, day_seconds, nondim_flag)
subroutine, public dcdate_nondimcheck(opr, diff1, diff2, rslt)
Derived types and parameters for date and time.
character(*), dimension(6), parameter, public unit_month
Strings recognized as month unit
character(*), dimension(1), parameter, public unit_nondim
Strings recognized as nondimensional unit
real(dp), save, public day_seconds
Seconds per day (variable, default is Earth day)
type(dc_scaled_sec), save, public day_seconds_scl
Seconds per day (DC_SCALED_SEC type)
character(*), dimension(4), parameter, public unit_day
Strings recognized as day unit
logical, save, public flag_set_day_seconds_scl
Flag indicating if day_seconds_scl is set
character(*), dimension(8), parameter, public unit_sec
Strings recognized as second unit
character(*), dimension(8), parameter, public unit_hour
Strings recognized as hour unit
character(*), dimension(4), parameter, public unit_year
Strings recognized as year unit
character(*), dimension(4), parameter, public unit_min
Strings recognized as minute unit
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_edimtime
Definition dc_error.f90:550
Judge optional control parameters.
logical function, public present_and_not_empty(arg)
Scaled seconds module for precise time operations.
Handling character types.
Definition dc_string.f90:83
Provides kind type parameter values.
Definition dc_types.f90:55
integer, parameter, public token
Character length for word, token
Definition dc_types.f90:128
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