source: ruby/trunk/lib/models/assumed_library_types.rb@ 124

Last change on this file since 124 was 124, checked in by KOBAYASHI, Shinji, 15 years ago

refs #48,#50

File size: 10.9 KB
Line 
1# This module is related to the ticket #36
2require 'date'
3require 'time'
4
5module OpenEHR
6 module Assumed_Library_Types
7 class Any < Object
8
9 end # of Any
10 class Interval < Any
11 attr_reader :lower, :lower_included, :lower_unbounded
12 attr_reader :upper, :upper_included, :upper_unbounded
13 def initialize(lower, upper,
14 lower_included = nil, upper_included = nil)
15 check_lower_upper(lower, upper)
16 set_lower_included(lower_included)
17 set_upper_included(upper_included)
18 end
19
20 def set_lower(lower)
21 check_lower_upper(lower, @upper)
22 end
23
24 def set_upper(upper)
25 check_lower_upper(@lower, upper)
26 end
27
28 def set_lower_included(lower_included)
29 if (lower == nil) && (lower_included != nil)
30 raise ArgumentError, "lower is not set"
31 end
32 @lower_included = lower_included
33 end
34
35 def set_upper_included(upper_included)
36 @upper_included = upper_included
37 if (upper == nil) && (upper_included != nil)
38 raise ArgumentError, "upper is not set"
39 end
40 end
41
42 def has?(value)
43 if ((@lower < value) && (value < @upper) ||
44 (@lower_included == true) && (@lower == value) ||
45 (@upper_included == true) && (@upper == value))
46 true
47 else
48 false
49 end
50 end
51
52 private
53
54 def check_lower_upper(lower, upper)
55 if (lower == nil) && (upper == nil)
56 raise ArgumentError, "Either lower or upper must be assigned"
57 end
58 if (lower == nil) && (upper != nil)
59 @lower_unbounded = true
60 elsif (lower != nil) && (upper == nil)
61 @upper_unbounded = true
62 elsif lower > upper
63 raise ArgumentError, "Upper must be larger than lower."
64 end
65 @lower = lower
66 @upper = upper
67 end
68 end # end of Interval
69
70 class TIME_DEFINITIONS < Any
71 DAYS_IN_LEAP_YEAR = 366
72 DAYS_IN_WEEK = 7
73 DAYS_IN_YEAR = 365
74 HOURS_IN_DAY = 24
75 MAX_DAYS_IN_MONTH = 31
76 MAX_DAYS_IN_YEAR = 366
77 MINUTES_IN_HOUR = 60
78 MONTH_IN_YEAR = 12
79 NOMINAL_DAYS_IN_MONTH = 30.42
80 NOMINAL_DAYS_IN_YEAR = 365.24
81 SECONDS_IN_MINUTE = 60
82
83 def self.valid_year?(year)
84 year >= 0
85 end
86
87 def self.valid_day?(y, m, d)
88 Date.valid_date?(y,m,d) and valid_year? y
89 end
90
91 def self.valid_hour?(h,m = nil, s = nil)
92 if !m.nil? and !valid_minute?(m)
93 return false
94 end
95 if !s.nil? and (!m.nil? and !valid_second?(s))
96 return false
97 end
98 (h >= 0 and h < HOURS_IN_DAY) or (h == HOURS_IN_DAY and m == 0 and s == 0)
99 end
100 def self.valid_minute?(mi)
101 mi >= 0 and mi < MINUTES_IN_HOUR
102 end
103 def self.valid_second?(s)
104 s >= 0 and s < SECONDS_IN_MINUTE
105 end
106 def self.valid_month?(mo)
107 mo >= 1 and mo <= MONTH_IN_YEAR
108 end
109 end # end of TIME_DEFINITIONS
110
111 module ISO8601_DATE_MODULE
112 attr_reader :year, :month, :day
113 def year=(year)
114 raise ArgumentError, "Year is not valid" unless ISO8601_DATE.valid_year?(year)
115 @year = year
116 end
117 def month=(month)
118 raise ArgumentError, "Month is not valid" unless month.nil? or ISO8601_DATE.valid_month?(month)
119 @month = month
120 end
121 def day=(day)
122 raise ArgumentError, "Day is not valid" unless day.nil? or ISO8601_DATE.valid_day?(@year, @month, day)
123 @day = day
124 end
125 def as_string
126 if (!@year.nil? and !@month.nil? and !@day.nil?)
127 Date.new(@year, @month, @day).to_s
128 elsif (!@year.nil? and !@month.nil? and @day.nil?)
129 Date.new(@year, @month).to_s[0,7]
130 elsif (!@year.nil? and @month.nil? and @day.nil?)
131 Date.new(@year).to_s[0,4]
132 end
133 end
134 def month_unknown?
135 @month.nil?
136 end
137 def day_unknown?
138 @day.nil?
139 end
140 def is_extended?
141 true
142 end
143 def is_partial?
144 month_unknown? or day_unknown?
145 end
146 end
147
148 class ISO8601_DATE < TIME_DEFINITIONS
149 include ISO8601_DATE_MODULE
150 def initialize(string)
151 /(\d{4})(?:-(\d{2})(?:-(\d{2})?)?)?/ =~ string
152 if $1.nil?
153 raise ArgumentError, 'data invalid'
154 else
155 self.year = $1.to_i
156 end
157 if $2.nil?
158 self.month = nil
159 else
160 self.month = $2.to_i
161 end
162 if $3.nil?
163 self.day = nil
164 else
165 self.day = $3.to_i
166 end
167 end
168 def self.valid_iso8601_date?(string)
169 begin
170 Date.parse(string)
171 rescue
172 return false
173 end
174 true
175 end
176 end # end of ISO8601_DATE
177
178 module ISO8601_TIME_MODULE
179 attr_reader :hour, :minute, :second, :fractional_second, :timezone
180
181 def hour=(hour)
182 raise ArgumentError, "hour is not valid" if !ISO8601_TIME.valid_hour?(hour, @minute, @second)
183 @hour = hour
184 end
185
186 def minute_unknown?
187 @minute.nil?
188 end
189
190 def minute=(minute)
191 raise ArgumentError, "minute is not valid" if !minute.nil? and !ISO8601_TIME.valid_minute?(minute)
192 @minute = minute
193 end
194
195 def second_unknown?
196 @second.nil?
197 end
198
199 def second=(second)
200 raise ArgumentError, "minute not defined" if @minute.nil? and !second.nil?
201 raise ArgumentError, "second is not valid" if !second.nil? and !ISO8601_TIME.valid_second?(second)
202 @second = second
203 end
204
205 def fractional_second=(fractional_second)
206 raise ArgumentError, "minute not defined" if minute_unknown? and !fractional_second.nil?
207 raise ArgumentError, "second not defined" if second_unknown? and !fractional_second.nil?
208 raise ArgumentError, "fractional second should be lower than 1.0" if !fractional_second.nil? and fractional_second >= 1.0
209 @fractional_second = fractional_second
210 end
211
212 def has_fractional_second?
213 if @fractional_second.nil?
214 return false
215 else
216 return true
217 end
218 end
219
220 def timezone=(timezone)
221 unless timezone.nil? or timezone == 'Z'
222 if /[+-](\d{2}):?(\d{2})/ =~ timezone
223 @timezone = timezone
224 else
225 raise ArgumentError, "timezone invalid"
226 end
227 else
228 @timezone = nil
229 end
230 end
231
232 def is_decimal_sign_comma?
233 true
234 end
235
236 def is_extended?
237 true
238 end
239
240 def is_partial?
241 second_unknown? or minute_unknown?
242 end
243 def as_string
244 s = sprintf("%02d", @hour)
245 if !@minute.nil?
246 s += ":" + sprintf("%02d",@minute)
247 if !@second.nil?
248 s += ":" + sprintf("%02d", @second)
249 if !@fractional_second.nil?
250 s += "," + @fractional_second.to_s[2..-1]
251 if !@timezone.nil?
252 s += @timezone
253 end
254 end
255 end
256 end
257 s
258 end
259 end
260
261 class ISO8601_TIME < TIME_DEFINITIONS
262 include ISO8601_TIME_MODULE
263 def initialize(string)
264 /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ string
265 if $2.nil?
266 self.minute = nil
267 else
268 self.minute = $2.to_i
269 end
270 if $4.nil?
271 self.second = nil
272 else
273 self.second = $4.to_i
274 end
275 if $1.nil?
276 raise ArgumentError, 'data invalid'
277 else
278 self.hour = $1.to_i
279 end
280 if $7.nil?
281 self.fractional_second = nil
282 else
283 self.fractional_second = ("0." + $7).to_f
284 end
285 if $8.nil?
286 self.timezone = nil
287 else
288 self.timezone = $8
289 end
290 end
291 def self.valid_iso8601_time?(s)
292 if /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ s
293# ISO 8601 regular expression by H. Yuki
294# http://digit.que.ne.jp/work/wiki.cgi?Perl%E3%83%A1%E3%83%A2%2FW3C%E5%BD%A2%E5%BC%8F%E3%81%AE%E6%97%A5%E6%99%82%E3%81%AE%E8%A7%A3%E6%9E%90
295# (\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d))?)?(Z|([+-]\d{2}):(\d{2}))?)?)?)?
296 hh = $1; mm = $2; ss = $4; msec = $7; tz = $8
297 if hh.to_i == HOURS_IN_DAY and (mm.nil? or mm.to_i == 0) and (ss.nil? or ss.to_i == 0) and (msec.nil? or msec.to_i==0)
298 return true
299 end
300 if hh.nil? or (hh.to_i < 0 or hh.to_i >= HOURS_IN_DAY)
301 return false
302 end
303 if !mm.nil?
304 if !self.valid_minute?(mm.to_i)
305 return false
306 end
307 end
308 if !ss.nil?
309 if !self.valid_second?(ss.to_i)
310 return false
311 end
312 end
313 if !tz.nil? and tz != "Z"
314 if /[+-](\d{2}):?(\d{2})/ =~ tz
315 h = $1; m = $2
316 if h.to_i < 0 or h.to_i >= HOURS_IN_DAY
317 return false
318 end
319 if m.to_i < 0 or m.to_i >= MINUTES_IN_HOUR
320 return false
321 end
322 else
323 return false
324 end
325 end
326 return true
327 else
328 return false
329 end
330 end
331 end # end of ISO8601_TIME
332
333 class ISO8601_DATE_TIME < ISO8601_DATE
334 include ISO8601_DATE_MODULE, ISO8601_TIME_MODULE
335 def initialize(string)
336 /(\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|([+-]\d{2}):?(\d{2}))?)?)?)?/ =~ string
337 if $1.empty?
338 raise ArgumentError, 'format invalid'
339 else
340 self.year = $1.to_i
341 end
342 if $2.nil?
343 self.month = nil
344 else
345 self.month = $2.to_i
346 end
347 if $3.nil?
348 self.day = nil
349 else
350 self.day = $3.to_i
351 end
352 if $5.nil?
353 self.minute = nil
354 else
355 self.minute = $5.to_i
356 end
357 if $6.nil?
358 self.second = nil
359 else
360 self.second = $6.to_i
361 end
362 if $4.nil?
363 self.hour = nil
364 else
365 self.hour = $4.to_i
366 end
367 if $7.nil? or $7.empty?
368 self.fractional_second = nil
369 else
370 self.fractional_second = ("0."+$7).to_f
371 end
372 if $8.nil?
373 self.timezone = nil
374 else
375 self.timezone = $9+$10
376 end
377 end
378 end
379
380 class ISO8601_TIMEZONE
381 attr_accessor :sign, :hour, :minute
382
383 def is_gmt?
384 @sign == "+1" and @hour == 0 and @minute == 0
385 end
386
387 def as_string
388 if @sign == "+1"
389 s = "+"
390 elsif @sign == "-1"
391 s = "-"
392 end
393 sprintf("Z%s%02d%02d", s, @hour, @minute)
394 end
395 end # end of ISO8601_TIMEZONE
396
397 class ISO8601_DURATION
398
399 def initialize
400
401 end
402
403 def as_string
404
405 end
406 end # end of ISO8601_DURATION
407 end # end of Assumed_Types
408end # end of OpenEHR
Note: See TracBrowser for help on using the repository browser.