dc_date_internal.f90
Go to the documentation of this file.
1 != dc_date 内で使用される内部向け定数, 変数, 手続き群
2 != Internal constants, variables, procedures used in "dc_date"
3 !
4 ! Authors:: Yasuhiro MORIKAWA, Eizi TOYODA
5 ! Version:: $Id: dc_date_internal.f90,v 1.1 2009-05-25 10:01:34 morikawa Exp $
6 ! Tag Name:: $Name: $
7 ! Copyright:: Copyright (C) GFD Dennou Club, 2000-2005. All rights reserved.
8 ! License:: See COPYRIGHT[link:../../COPYRIGHT]
9 
11  != dc_date 内で使用される内部向け定数, 変数, 手続き群
12  != Internal constants, variables, procedures used in "dc_date"
13 
15  use dc_types, only: dp, string, token
17 
18  implicit none
19 
20  private
22  public:: dcdate_nondimcheck
23 
24 contains
25 
26  subroutine dcdate_normalize(day, sec, day_seconds, nondim_flag)
27  !
28  !=== 日と秒の正規化
29  !
30  ! このサブルーチンは内部向けなので dc_date モジュール外では
31  ! 極力使用しないでください.
32  !
33  ! 日付 *day* と秒数 *sec* の正規化を行います. *sec* が *day_seconds*
34  ! (省略される場合は dc_date_types#day_seconds) を超える場合, *day*
35  ! に繰上げを行います.
36  ! また, *sec* と *day* の符号が逆の場合, 同符号になるよう
37  ! 設定します.
38  !
39  use dc_date_types, only: &
41  use dc_scaledsec, only: dc_scaled_sec, &
42  & operator(<), operator(>), operator(<=), operator(>=), &
43  & operator(+), operator(-), operator(*), operator(/), &
44  & modulo, int, abs, sign
45  implicit none
46  type(dc_scaled_sec), intent(inout):: day
47  type(dc_scaled_sec), intent(inout):: sec
48  type(dc_scaled_sec), intent(in), optional:: day_seconds
49  logical, intent(in):: nondim_flag
50  type(dc_scaled_sec):: sgn, day_sec, zero_sec
51  continue
52  if ( nondim_flag ) return
53  if (present(day_seconds)) then
54  day_sec = day_seconds
55  else
57  day_sec = day_seconds_scl
58  end if
59  if (abs(sec) >= day_sec) then
60  day = day + int(sec / day_sec)
61  sec = modulo(sec, day_sec)
62  end if
63 !! zero_sec = 0 (デフォルト値 = 0 を使用する).
64  if ( ( sec > zero_sec .and. day < zero_sec ) &
65  & .or. ( sec < zero_sec .and. day > zero_sec ) ) then
66  sgn = sign(day, 1)
67  day = day - sgn
68  sec = sec + sgn * day_sec
69  endif
70  end subroutine dcdate_normalize
71 
73  use dc_scaledsec, only: dc_scaled_sec, assignment(=)
74  use dc_date_types, only: day_seconds, &
76  continue
77  if ( .not. flag_set_day_seconds_scl ) then
80  end if
81  end subroutine dcdate_set_day_seconds_scl
82 
83  subroutine dcdate_nondimcheck(opr, diff1, diff2, rslt)
84  !
85  ! このサブルーチンは内部向けなので dc_date モジュール外では
86  ! 極力使用しないでください.
87  !
88  ! diff1 と diff2 が両方とも有次元もしくは無次元かをチェックし,
89  ! 両方が同じであれば, その結果を rslt に適用します.
90  ! 2つの引数で片方が有次元, もう片方が無次元の場合には
91  ! エラーを発生させます.
92  !
93  use dc_error, only: storeerror, dc_edimtime
94  implicit none
95  character(*), intent(in):: opr ! 演算子の名称
96  type(dc_difftime), intent(in):: diff1, diff2
97  type(dc_difftime), intent(inout):: rslt
98  continue
99  if ( ( diff1 % nondim_flag .and. .not. diff2 % nondim_flag ) &
100  & .or. ( .not. diff1 % nondim_flag .and. diff2 % nondim_flag ) ) then
101  call storeerror(dc_edimtime, opr)
102  end if
103  rslt % nondim_flag = diff1 % nondim_flag
104  end subroutine dcdate_nondimcheck
105 
106  function parsetimeunits(str) result(symbol)
107  !
108  ! 引数 *str* に与えられた文字列を解釈し, 日時の単位を示す
109  ! シンボルを返します. それぞれ以下の文字列が日時の単位として解釈されます.
110  ! 大文字と小文字は区別されません.
111  !
112  ! 年 :: dc_date_types#UNIT_YEAR
113  ! 月 :: dc_date_types#UNIT_MONTH
114  ! 日 :: dc_date_types#UNIT_DAY
115  ! 時 :: dc_date_types#UNIT_HOUR
116  ! 分 :: dc_date_types#UNIT_MIN
117  ! 秒 :: dc_date_types#UNIT_SEC
118  ! 無次元時間 :: dc_date_types#UNIT_NONDIM
119  !
120  ! 返るシンボル (整数型) は以下の通りです.
121  !
122  ! 年 :: dc_date_types#UNIT_SYMBOL_YEAR
123  ! 月 :: dc_date_types#UNIT_SYMBOL_MONTH
124  ! 日 :: dc_date_types#UNIT_SYMBOL_DAY
125  ! 時 :: dc_date_types#UNIT_SYMBOL_HOUR
126  ! 分 :: dc_date_types#UNIT_SYMBOL_MIN
127  ! 秒 :: dc_date_types#UNIT_SYMBOL_SEC
128  ! 無次元時間 :: dc_date_types#UNIT_SYMBOL_NONDIM
129  !
130  ! これらに該当しない文字列を *str* に与えた場合,
131  ! dc_date_types#UNIT_SYMBOL_ERR が返ります.
132  !
133  use dc_types, only: token
139  use dc_string, only: strieq
140  implicit none
141  character(*), intent(in):: str
142  integer:: symbol
143  integer:: unit_str_size, i
144  character(TOKEN):: unit
145  continue
146  unit = adjustl(str)
147  unit_str_size = size(unit_nondim)
148  do i = 1, unit_str_size
149  if (strieq(trim(unit), trim(unit_nondim(i)))) then
150  symbol = unit_symbol_nondim
151  return
152  end if
153  end do
154 
155  unit_str_size = size(unit_sec)
156  do i = 1, unit_str_size
157  if (strieq(trim(unit), trim(unit_sec(i)))) then
158  symbol = unit_symbol_sec
159  return
160  end if
161  end do
162 
163  unit_str_size = size(unit_min)
164  do i = 1, unit_str_size
165  if (strieq(trim(unit), trim(unit_min(i)))) then
166  symbol = unit_symbol_min
167  return
168  end if
169  end do
170 
171  unit_str_size = size(unit_hour)
172  do i = 1, unit_str_size
173  if (strieq(trim(unit), trim(unit_hour(i)))) then
174  symbol = unit_symbol_hour
175  return
176  end if
177  end do
178 
179  unit_str_size = size(unit_day)
180  do i = 1, unit_str_size
181  if (strieq(trim(unit), trim(unit_day(i)))) then
182  symbol = unit_symbol_day
183  return
184  end if
185  end do
186 
187  unit_str_size = size(unit_month)
188  do i = 1, unit_str_size
189  if (strieq(trim(unit), trim(unit_month(i)))) then
190  symbol = unit_symbol_month
191  return
192  end if
193  end do
194 
195  unit_str_size = size(unit_year)
196  do i = 1, unit_str_size
197  if (strieq(trim(unit), trim(unit_year(i)))) then
198  symbol = unit_symbol_year
199  return
200  end if
201  end do
202 
203  symbol = unit_symbol_err
204 
205  end function parsetimeunits
206 
207  character(TOKEN) function dcdate_parse_unit(str) result(unit)
208  !
209  ! このサブルーチンは内部向けなので dc_date モジュール外では
210  ! 極力使用しないでください.
211  !
212  ! 引数 *str* に与えられた文字列を解釈し, 日時の単位を
213  ! 返します. それぞれ以下の文字列が日時の単位として解釈されます.
214  ! 大文字と小文字は区別されません.
215  ! 返る文字列は以下の文字型の配列の先頭の文字列です.
216  ! (例: *str* に 'hrs.' が与えられる場合, dc_date_types#UNIT_HOUR
217  ! 配列の先頭の文字列 UNIT_HOUR(1) が返ります.)
218  !
219  ! 年 :: dc_date_types#UNIT_YEAR
220  ! 月 :: dc_date_types#UNIT_MONTH
221  ! 日 :: dc_date_types#UNIT_DAY
222  ! 時 :: dc_date_types#UNIT_HOUR
223  ! 分 :: dc_date_types#UNIT_MIN
224  ! 秒 :: dc_date_types#UNIT_SEC
225  ! 無次元時間 :: dc_date_types#UNIT_NONDIM
226  !
227  ! これらに該当しない文字列を *str* に与えた場合, 空文字が返ります.
228  !
229  use dc_types, only: token
232  use dc_string, only: strieq
233  implicit none
234  character(*), intent(in):: str
235  integer :: unit_str_size, i
236  continue
237  unit = adjustl(str)
238  unit_str_size = size(unit_nondim)
239  do i = 1, unit_str_size
240  if (strieq(trim(unit), trim(unit_nondim(i)))) then
241  unit = unit_nondim(1)
242  return
243  end if
244  end do
245 
246  unit_str_size = size(unit_sec)
247  do i = 1, unit_str_size
248  if (strieq(trim(unit), trim(unit_sec(i)))) then
249  unit = unit_sec(1)
250  return
251  end if
252  end do
253 
254  unit_str_size = size(unit_min)
255  do i = 1, unit_str_size
256  if (strieq(trim(unit), trim(unit_min(i)))) then
257  unit = unit_min(1)
258  return
259  end if
260  end do
261 
262  unit_str_size = size(unit_hour)
263  do i = 1, unit_str_size
264  if (strieq(trim(unit), trim(unit_hour(i)))) then
265  unit = unit_hour(1)
266  return
267  end if
268  end do
269 
270  unit_str_size = size(unit_day)
271  do i = 1, unit_str_size
272  if (strieq(trim(unit), trim(unit_day(i)))) then
273  unit = unit_day(1)
274  return
275  end if
276  end do
277 
278  unit_str_size = size(unit_month)
279  do i = 1, unit_str_size
280  if (strieq(trim(unit), trim(unit_month(i)))) then
281  unit = unit_month(1)
282  return
283  end if
284  end do
285 
286  unit_str_size = size(unit_year)
287  do i = 1, unit_str_size
288  if (strieq(trim(unit), trim(unit_year(i)))) then
289  unit = unit_year(1)
290  return
291  end if
292  end do
293 
294  unit = ''
295 
296  end function dcdate_parse_unit
297 
298 end module dc_date_internal
integer, parameter, public unit_symbol_nondim
character(*), dimension(4), parameter, public unit_min
character(*), dimension(4), parameter, public unit_day
integer, parameter, public unit_symbol_month
integer, parameter, public unit_symbol_err
integer, parameter, public unit_symbol_min
integer, parameter, public token
Character length for word, token.
Definition: dc_types.f90:109
subroutine, public dcdate_set_day_seconds_scl
integer, parameter, public unit_symbol_hour
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition: dc_error.f90:830
character(*), dimension(8), parameter, public unit_hour
character(*), dimension(1), parameter, public unit_nondim
character(*), dimension(4), parameter, public unit_year
subroutine, public dcdate_nondimcheck(opr, diff1, diff2, rslt)
integer, parameter, public dp
Double Precision Real number.
Definition: dc_types.f90:83
logical function, public present_and_not_empty(arg)
Definition: dc_present.f90:276
integer function parsetimeunits(str)
Handling character types.
Definition: dc_string.f90:24
Provides kind type parameter values.
Definition: dc_types.f90:49
logical, save, public flag_set_day_seconds_scl
integer, parameter, public unit_symbol_sec
integer, parameter, public unit_symbol_day
integer, parameter, public dc_edimtime
Definition: dc_error.f90:573
character(token) function, public dcdate_parse_unit(str)
real(dp), save, public day_seconds
integer, parameter, public unit_symbol_year
character(*), dimension(8), parameter, public unit_sec
type(dc_scaled_sec), save, public day_seconds_scl
subroutine, public dcdate_normalize(day, sec, day_seconds, nondim_flag)
character(*), dimension(6), parameter, public unit_month
integer, parameter, public string
Character length for string.
Definition: dc_types.f90:118