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

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

fixed #36

File size: 14.3 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
122 def day=(day)
123 raise ArgumentError, "Day is not valid" unless day.nil? or ISO8601_DATE.valid_day?(@year, @month, day)
124 @day = day
125 end
126
127 def as_string
128 if (!@year.nil? and !@month.nil? and !@day.nil?)
129 Date.new(@year, @month, @day).to_s
130 elsif (!@year.nil? and !@month.nil? and @day.nil?)
131 Date.new(@year, @month).to_s[0,7]
132 elsif (!@year.nil? and @month.nil? and @day.nil?)
133 Date.new(@year).to_s[0,4]
134 end
135 end
136
137 def month_unknown?
138 @month.nil?
139 end
140
141 def day_unknown?
142 @day.nil?
143 end
144
145 def is_extended?
146 true
147 end
148
149 def is_partial?
150 month_unknown? or day_unknown?
151 end
152 end
153
154 class ISO8601_DATE < TIME_DEFINITIONS
155 include ISO8601_DATE_MODULE
156 def initialize(string)
157 /(\d{4})(?:-(\d{2})(?:-(\d{2})?)?)?/ =~ string
158 if $1.nil?
159 raise ArgumentError, 'data invalid'
160 else
161 self.year = $1.to_i
162 end
163 if $2.nil?
164 self.month = nil
165 else
166 self.month = $2.to_i
167 end
168 if $3.nil?
169 self.day = nil
170 else
171 self.day = $3.to_i
172 end
173 end
174 def self.valid_iso8601_date?(string)
175 begin
176 Date.parse(string)
177 rescue
178 return false
179 end
180 true
181 end
182 end # end of ISO8601_DATE
183
184 module ISO8601_TIME_MODULE
185 attr_reader :hour, :minute, :second, :fractional_second, :timezone
186
187 def hour=(hour)
188 raise ArgumentError, "hour is not valid" if !ISO8601_TIME.valid_hour?(hour, @minute, @second)
189 @hour = hour
190 end
191
192 def minute_unknown?
193 @minute.nil?
194 end
195
196 def minute=(minute)
197 raise ArgumentError, "minute is not valid" if !minute.nil? and !ISO8601_TIME.valid_minute?(minute)
198 @minute = minute
199 end
200
201 def second_unknown?
202 @second.nil?
203 end
204
205 def second=(second)
206 raise ArgumentError, "minute not defined" if @minute.nil? and !second.nil?
207 raise ArgumentError, "second is not valid" if !second.nil? and !ISO8601_TIME.valid_second?(second)
208 @second = second
209 end
210
211 def fractional_second=(fractional_second)
212 raise ArgumentError, "minute not defined" if minute_unknown? and !fractional_second.nil?
213 raise ArgumentError, "second not defined" if second_unknown? and !fractional_second.nil?
214 raise ArgumentError, "fractional second should be lower than 1.0" if !fractional_second.nil? and fractional_second >= 1.0
215 @fractional_second = fractional_second
216 end
217
218 def has_fractional_second?
219 if @fractional_second.nil?
220 return false
221 else
222 return true
223 end
224 end
225
226 def timezone=(timezone)
227 unless timezone.nil? or timezone == 'Z'
228 if /[+-](\d{2}):?(\d{2})/ =~ timezone
229 @timezone = timezone
230 else
231 raise ArgumentError, "timezone invalid"
232 end
233 else
234 @timezone = nil
235 end
236 end
237
238 def is_decimal_sign_comma?
239 false
240 end
241
242 def is_extended?
243 true
244 end
245
246 def is_partial?
247 second_unknown? or minute_unknown?
248 end
249
250 def as_string
251 s = sprintf("%02d", @hour)
252 if !@minute.nil?
253 s += ":" + sprintf("%02d",@minute)
254 if !@second.nil?
255 s += ":" + sprintf("%02d", @second)
256 if !@fractional_second.nil?
257 s += "." + @fractional_second.to_s[2..-1]
258 if !@timezone.nil?
259 s += @timezone
260 end
261 end
262 end
263 end
264 return s
265 end
266 end
267
268 class ISO8601_TIME < TIME_DEFINITIONS
269 include ISO8601_TIME_MODULE
270 def initialize(string)
271 /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ string
272 if $2.nil?
273 self.minute = nil
274 else
275 self.minute = $2.to_i
276 end
277 if $4.nil?
278 self.second = nil
279 else
280 self.second = $4.to_i
281 end
282 if $1.nil?
283 raise ArgumentError, 'data invalid'
284 else
285 self.hour = $1.to_i
286 end
287 if $7.nil?
288 self.fractional_second = nil
289 else
290 self.fractional_second = ("0." + $7).to_f
291 end
292 if $8.nil?
293 self.timezone = nil
294 else
295 self.timezone = $8
296 end
297 end
298 def self.valid_iso8601_time?(s)
299 if /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ s
300# ISO 8601 regular expression by H. Yuki
301# 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
302# (\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d))?)?(Z|([+-]\d{2}):(\d{2}))?)?)?)?
303 hh = $1; mm = $2; ss = $4; msec = $7; tz = $8
304 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)
305 return true
306 end
307 if hh.nil? or (hh.to_i < 0 or hh.to_i >= HOURS_IN_DAY)
308 return false
309 end
310 if !mm.nil?
311 if !self.valid_minute?(mm.to_i)
312 return false
313 end
314 end
315 if !ss.nil?
316 if !self.valid_second?(ss.to_i)
317 return false
318 end
319 end
320 if !tz.nil? and tz != "Z"
321 if /[+-](\d{2}):?(\d{2})/ =~ tz
322 h = $1; m = $2
323 if h.to_i < 0 or h.to_i >= HOURS_IN_DAY
324 return false
325 end
326 if m.to_i < 0 or m.to_i >= MINUTES_IN_HOUR
327 return false
328 end
329 else
330 return false
331 end
332 end
333 return true
334 else
335 return false
336 end
337 end
338 end # end of ISO8601_TIME
339
340 class ISO8601_DATE_TIME < ISO8601_DATE
341 include ISO8601_TIME_MODULE, ISO8601_DATE_MODULE
342 def initialize(string)
343 /(\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|([+-]\d{2}):?(\d{2}))?)?)?)?/ =~ string
344 if $1.empty?
345 raise ArgumentError, 'format invalid'
346 else
347 self.year = $1.to_i
348 end
349 if $2.nil?
350 self.month = nil
351 else
352 self.month = $2.to_i
353 end
354 if $3.nil?
355 self.day = nil
356 else
357 self.day = $3.to_i
358 end
359 if $5.nil?
360 self.minute = nil
361 else
362 self.minute = $5.to_i
363 end
364 if $6.nil?
365 self.second = nil
366 else
367 self.second = $6.to_i
368 end
369 if $4.nil?
370 self.hour = nil
371 else
372 self.hour = $4.to_i
373 end
374 if $7.nil? or $7.empty?
375 self.fractional_second = nil
376 else
377 self.fractional_second = ("0."+$7).to_f
378 end
379 if $8.nil?
380 self.timezone = nil
381 else
382 self.timezone = $9+$10
383 end
384 end
385
386 def as_string
387 if (!@year.nil? and !@month.nil? and !@day.nil?)
388 s = Date.new(@year, @month, @day).to_s
389 elsif (!@year.nil? and !@month.nil? and @day.nil?)
390 return Date.new(@year, @month).to_s[0,7]
391 elsif (!@year.nil? and @month.nil? and @day.nil?)
392 return Date.new(@year).to_s[0,4]
393 end
394 unless hour.nil?
395 s += sprintf("T%02d", @hour)
396 unless @minute.nil?
397 s += ":" + sprintf("%02d",@minute)
398 unless @second.nil?
399 s += ":" + sprintf("%02d", @second)
400 unless @fractional_second.nil?
401 s += "." + @fractional_second.to_s[2..-1]
402 unless @timezone.nil?
403 s += @timezone
404 end
405 end
406 end
407 end
408 end
409 return s
410 end
411
412 end
413
414 class ISO8601_TIMEZONE
415 attr_accessor :sign, :hour, :minute
416
417 def is_gmt?
418 @sign == "+1" and @hour == 0 and @minute == 0
419 end
420
421 def as_string
422 if @sign == "+1"
423 s = "+"
424 elsif @sign == "-1"
425 s = "-"
426 end
427 sprintf("Z%s%02d%02d", s, @hour, @minute)
428 end
429 end # end of ISO8601_TIMEZONE
430
431 class ISO8601_DURATION < TIME_DEFINITIONS
432 attr_reader :years, :months, :weeks, :days
433 attr_reader :hours, :minutes, :seconds, :fractional_second
434
435 def initialize(str)
436 /^P((\d+)Y)?((\d+)M)?((\d+)W)?((\d)D)?(T((\d+)H)?((\d+)M)?((\d+)(\.\d+)?S)?)?$/ =~ str
437 self.years = $2.to_i
438 self.months = $4.to_i
439 self.weeks = $6.to_i
440 self.days = $8.to_i
441 self.hours = $11.to_i
442 self.minutes = $13.to_i
443 self.seconds = $15.to_i
444 self.fractional_second = $16.to_f
445 end
446
447 def years=(years)
448 unless years.nil? || years > 0
449 raise ArgumentError, 'years must be above zero'
450 end
451 @years = years
452 end
453
454 def months=(months)
455 unless months.nil? || months > 0
456 raise ArgumentError, 'months must be above zero'
457 end
458 @months = months
459 end
460
461 def weeks=(weeks)
462 unless weeks.nil? || weeks > 0
463 raise ArgumentError, 'weeks must be above zero'
464 end
465 @weeks = weeks
466 end
467
468 def days=(days)
469 unless days.nil? || days > 0
470 raise ArgumentError, 'days must be above zero'
471 end
472 @days = days
473 end
474
475 def hours=(hours)
476 unless hours.nil? || hours > 0
477 raise ArgumentError, 'hours must be above zero'
478 end
479 @hours = hours
480 end
481
482 def minutes=(minutes)
483 unless minutes.nil? || minutes > 0
484 raise ArgumentError, 'minutes must be above zero'
485 end
486 @minutes = minutes
487 end
488
489 def seconds=(seconds)
490 unless seconds.nil? || seconds > 0
491 raise ArgumentError, 'seconds must be above zero'
492 end
493 @seconds = seconds
494 end
495
496 def fractional_second=(fractional_second)
497 unless fractional_second.nil? || (fractional_second > 0 && fractional_second < 1.0)
498 raise ArgumentError, 'fractional_second must be between 0.0 and 1.0'
499 end
500 @fractional_second = fractional_second
501 end
502
503 def as_string
504 str = 'P'
505 unless @years.nil?
506 str += @years.to_s + 'Y'
507 end
508 unless @months.nil?
509 str += @months.to_s + 'M'
510 end
511 unless @weeks.nil?
512 str += @weeks.to_s + 'W'
513 end
514 unless @days.nil?
515 str += @days.to_s + 'D'
516 end
517 unless @hours.nil?
518 str += 'T' + @hours.to_s + 'H'
519 unless @minutes.nil?
520 str += @minutes.to_s + 'M'
521 unless @seconds.nil?
522 str += @seconds.to_s
523 unless @fractional_second.nil?
524 str += @fractional_second.to_s[1 .. -1]
525 end
526 str += 'S'
527 end
528 end
529 end
530 return str
531 end
532 end # end of ISO8601_DURATION
533 end # end of Assumed_Types
534end # end of OpenEHR
Note: See TracBrowser for help on using the repository browser.