source: ruby/branches/0.5/lib/open_ehr/assumed_library_types.rb@ 216

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

move from Test:Unit to RSpec

File size: 14.7 KB
RevLine 
[83]1# This module is related to the ticket #36
[70]2require 'date'
[81]3require 'time'
[70]4
[216]5module OpenEHR
[167]6 module AssumedLibraryTypes
[69]7 class Any < Object
8
9 end # of Any
[143]10
[69]11 class Interval < Any
[143]12 attr_reader :lower, :upper
13
[4]14 def initialize(lower, upper,
15 lower_included = nil, upper_included = nil)
16 check_lower_upper(lower, upper)
[143]17 self.lower_included = lower_included
18 self.upper_included = upper_included
[4]19 end
[21]20
[143]21 def lower=(lower)
[4]22 check_lower_upper(lower, @upper)
23 end
[21]24
[143]25 def upper=(upper)
[4]26 check_lower_upper(@lower, upper)
27 end
[21]28
[143]29 def lower_included?
30 return @lower_included
31 end
32
33 def lower_included=(lower_included)
[4]34 if (lower == nil) && (lower_included != nil)
35 raise ArgumentError, "lower is not set"
36 end
37 @lower_included = lower_included
38 end
[143]39
40 def lower_unbounded?
41 return @lower.nil?
42 end
[21]43
[143]44 def upper_included?
45 return @upper_included
46 end
47
48 def upper_included=(upper_included)
[4]49 if (upper == nil) && (upper_included != nil)
50 raise ArgumentError, "upper is not set"
51 end
[143]52 @upper_included = upper_included
[4]53 end
[21]54
[143]55 def upper_unbounded?
56 return @upper.nil?
57 end
58
[4]59 def has?(value)
60 if ((@lower < value) && (value < @upper) ||
61 (@lower_included == true) && (@lower == value) ||
62 (@upper_included == true) && (@upper == value))
63 true
64 else
65 false
66 end
67 end
[21]68
[4]69 private
[21]70
[4]71 def check_lower_upper(lower, upper)
72 if (lower == nil) && (upper == nil)
73 raise ArgumentError, "Either lower or upper must be assigned"
74 end
[143]75 unless (lower.nil? || upper.nil?)
76 if lower > upper
77 raise ArgumentError, "Upper must be larger than lower."
78 end
[4]79 end
80 @lower = lower
81 @upper = upper
[143]82 end
[69]83 end # end of Interval
[143]84
[69]85 class TIME_DEFINITIONS < Any
86 DAYS_IN_LEAP_YEAR = 366
87 DAYS_IN_WEEK = 7
88 DAYS_IN_YEAR = 365
89 HOURS_IN_DAY = 24
90 MAX_DAYS_IN_MONTH = 31
91 MAX_DAYS_IN_YEAR = 366
92 MINUTES_IN_HOUR = 60
93 MONTH_IN_YEAR = 12
94 NOMINAL_DAYS_IN_MONTH = 30.42
95 NOMINAL_DAYS_IN_YEAR = 365.24
96 SECONDS_IN_MINUTE = 60
[70]97
98 def self.valid_year?(year)
99 year >= 0
100 end
101
102 def self.valid_day?(y, m, d)
103 Date.valid_date?(y,m,d) and valid_year? y
104 end
105
[83]106 def self.valid_hour?(h,m = nil, s = nil)
107 if !m.nil? and !valid_minute?(m)
108 return false
109 end
110 if !s.nil? and (!m.nil? and !valid_second?(s))
111 return false
112 end
113 (h >= 0 and h < HOURS_IN_DAY) or (h == HOURS_IN_DAY and m == 0 and s == 0)
[70]114 end
[81]115 def self.valid_minute?(mi)
116 mi >= 0 and mi < MINUTES_IN_HOUR
[70]117 end
118 def self.valid_second?(s)
119 s >= 0 and s < SECONDS_IN_MINUTE
120 end
[81]121 def self.valid_month?(mo)
122 mo >= 1 and mo <= MONTH_IN_YEAR
[70]123 end
[69]124 end # end of TIME_DEFINITIONS
125
[120]126 module ISO8601_DATE_MODULE
[70]127 attr_reader :year, :month, :day
128 def year=(year)
[120]129 raise ArgumentError, "Year is not valid" unless ISO8601_DATE.valid_year?(year)
[70]130 @year = year
131 end
132 def month=(month)
[120]133 raise ArgumentError, "Month is not valid" unless month.nil? or ISO8601_DATE.valid_month?(month)
[70]134 @month = month
135 end
[125]136
[70]137 def day=(day)
[120]138 raise ArgumentError, "Day is not valid" unless day.nil? or ISO8601_DATE.valid_day?(@year, @month, day)
[70]139 @day = day
140 end
[125]141
[70]142 def as_string
143 if (!@year.nil? and !@month.nil? and !@day.nil?)
144 Date.new(@year, @month, @day).to_s
145 elsif (!@year.nil? and !@month.nil? and @day.nil?)
146 Date.new(@year, @month).to_s[0,7]
147 elsif (!@year.nil? and @month.nil? and @day.nil?)
148 Date.new(@year).to_s[0,4]
149 end
150 end
[125]151
[70]152 def month_unknown?
153 @month.nil?
154 end
[125]155
[70]156 def day_unknown?
157 @day.nil?
158 end
[125]159
[70]160 def is_extended?
161 true
162 end
[125]163
[70]164 def is_partial?
165 month_unknown? or day_unknown?
166 end
[149]167
168 protected
169 def leapyear?(year)
170 case
171 when year % 400 == 0: true
172 when year % 100 == 0: false
173 else year % 4 == 0
174 end
175 end
[120]176 end
177
178 class ISO8601_DATE < TIME_DEFINITIONS
179 include ISO8601_DATE_MODULE
180 def initialize(string)
181 /(\d{4})(?:-(\d{2})(?:-(\d{2})?)?)?/ =~ string
182 if $1.nil?
183 raise ArgumentError, 'data invalid'
184 else
185 self.year = $1.to_i
186 end
187 if $2.nil?
188 self.month = nil
189 else
190 self.month = $2.to_i
191 end
192 if $3.nil?
193 self.day = nil
194 else
195 self.day = $3.to_i
196 end
197 end
[149]198
[81]199 def self.valid_iso8601_date?(string)
[70]200 begin
[81]201 Date.parse(string)
[70]202 rescue
203 return false
204 end
205 true
206 end
[79]207 end # end of ISO8601_DATE
208
[120]209 module ISO8601_TIME_MODULE
[83]210 attr_reader :hour, :minute, :second, :fractional_second, :timezone
[120]211
[83]212 def hour=(hour)
213 raise ArgumentError, "hour is not valid" if !ISO8601_TIME.valid_hour?(hour, @minute, @second)
214 @hour = hour
215 end
[124]216
[83]217 def minute_unknown?
218 @minute.nil?
219 end
[124]220
[83]221 def minute=(minute)
222 raise ArgumentError, "minute is not valid" if !minute.nil? and !ISO8601_TIME.valid_minute?(minute)
223 @minute = minute
224 end
[124]225
[83]226 def second_unknown?
227 @second.nil?
228 end
[124]229
[83]230 def second=(second)
[120]231 raise ArgumentError, "minute not defined" if @minute.nil? and !second.nil?
[83]232 raise ArgumentError, "second is not valid" if !second.nil? and !ISO8601_TIME.valid_second?(second)
233 @second = second
234 end
[124]235
[83]236 def fractional_second=(fractional_second)
[120]237 raise ArgumentError, "minute not defined" if minute_unknown? and !fractional_second.nil?
238 raise ArgumentError, "second not defined" if second_unknown? and !fractional_second.nil?
239 raise ArgumentError, "fractional second should be lower than 1.0" if !fractional_second.nil? and fractional_second >= 1.0
[83]240 @fractional_second = fractional_second
241 end
[124]242
[83]243 def has_fractional_second?
244 if @fractional_second.nil?
245 return false
246 else
247 return true
248 end
249 end
[124]250
[120]251 def timezone=(timezone)
252 unless timezone.nil? or timezone == 'Z'
253 if /[+-](\d{2}):?(\d{2})/ =~ timezone
254 @timezone = timezone
255 else
256 raise ArgumentError, "timezone invalid"
257 end
258 else
259 @timezone = nil
260 end
261 end
[124]262
[83]263 def is_decimal_sign_comma?
[126]264 false
[83]265 end
[124]266
[83]267 def is_extended?
268 true
269 end
[124]270
[83]271 def is_partial?
272 second_unknown? or minute_unknown?
273 end
[125]274
[81]275 def as_string
[83]276 s = sprintf("%02d", @hour)
277 if !@minute.nil?
278 s += ":" + sprintf("%02d",@minute)
279 if !@second.nil?
280 s += ":" + sprintf("%02d", @second)
281 if !@fractional_second.nil?
[125]282 s += "." + @fractional_second.to_s[2..-1]
[83]283 if !@timezone.nil?
284 s += @timezone
[81]285 end
286 end
287 end
288 end
[125]289 return s
[81]290 end
[120]291 end
292
293 class ISO8601_TIME < TIME_DEFINITIONS
294 include ISO8601_TIME_MODULE
295 def initialize(string)
296 /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ string
297 if $2.nil?
298 self.minute = nil
299 else
300 self.minute = $2.to_i
301 end
302 if $4.nil?
303 self.second = nil
304 else
305 self.second = $4.to_i
306 end
307 if $1.nil?
308 raise ArgumentError, 'data invalid'
309 else
310 self.hour = $1.to_i
311 end
312 if $7.nil?
313 self.fractional_second = nil
314 else
315 self.fractional_second = ("0." + $7).to_f
316 end
317 if $8.nil?
318 self.timezone = nil
319 else
320 self.timezone = $8
321 end
322 end
[81]323 def self.valid_iso8601_time?(s)
324 if /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ s
325# ISO 8601 regular expression by H. Yuki
326# 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
327# (\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d))?)?(Z|([+-]\d{2}):(\d{2}))?)?)?)?
328 hh = $1; mm = $2; ss = $4; msec = $7; tz = $8
[83]329 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)
[81]330 return true
331 end
332 if hh.nil? or (hh.to_i < 0 or hh.to_i >= HOURS_IN_DAY)
333 return false
334 end
335 if !mm.nil?
336 if !self.valid_minute?(mm.to_i)
337 return false
338 end
339 end
340 if !ss.nil?
341 if !self.valid_second?(ss.to_i)
342 return false
343 end
344 end
345 if !tz.nil? and tz != "Z"
346 if /[+-](\d{2}):?(\d{2})/ =~ tz
347 h = $1; m = $2
348 if h.to_i < 0 or h.to_i >= HOURS_IN_DAY
349 return false
350 end
351 if m.to_i < 0 or m.to_i >= MINUTES_IN_HOUR
352 return false
353 end
354 else
355 return false
356 end
357 end
358 return true
359 else
360 return false
361 end
362 end
[79]363 end # end of ISO8601_TIME
364
[149]365 module ISO8601_DATE_TIME_MODULE
366 include ISO8601_DATE_MODULE, ISO8601_TIME_MODULE
367 def as_string
368 if (!@year.nil? and !@month.nil? and !@day.nil?)
369 s = Date.new(@year, @month, @day).to_s
370 elsif (!@year.nil? and !@month.nil? and @day.nil?)
371 return Date.new(@year, @month).to_s[0,7]
372 elsif (!@year.nil? and @month.nil? and @day.nil?)
373 return Date.new(@year).to_s[0,4]
374 end
375 unless hour.nil?
376 s += sprintf("T%02d", @hour)
377 unless @minute.nil?
378 s += ":" + sprintf("%02d",@minute)
379 unless @second.nil?
380 s += ":" + sprintf("%02d", @second)
381 unless @fractional_second.nil?
382 s += "." + @fractional_second.to_s[2..-1]
383 unless @timezone.nil?
384 s += @timezone
385 end
386 end
387 end
388 end
389 end
390 return s
391 end
392 end
393
[120]394 class ISO8601_DATE_TIME < ISO8601_DATE
[149]395 include ISO8601_DATE_TIME_MODULE
[120]396 def initialize(string)
[121]397 /(\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(Z|([+-]\d{2}):?(\d{2}))?)?)?)?/ =~ string
[120]398 if $1.empty?
399 raise ArgumentError, 'format invalid'
400 else
401 self.year = $1.to_i
402 end
403 if $2.nil?
404 self.month = nil
405 else
406 self.month = $2.to_i
407 end
408 if $3.nil?
409 self.day = nil
410 else
411 self.day = $3.to_i
412 end
413 if $5.nil?
414 self.minute = nil
415 else
416 self.minute = $5.to_i
417 end
418 if $6.nil?
419 self.second = nil
420 else
421 self.second = $6.to_i
422 end
423 if $4.nil?
424 self.hour = nil
425 else
426 self.hour = $4.to_i
427 end
[121]428 if $7.nil? or $7.empty?
[120]429 self.fractional_second = nil
430 else
431 self.fractional_second = ("0."+$7).to_f
432 end
433 if $8.nil?
434 self.timezone = nil
435 else
[121]436 self.timezone = $9+$10
[120]437 end
438 end
439 end
[149]440
[79]441 class ISO8601_TIMEZONE
442 attr_accessor :sign, :hour, :minute
[124]443
[79]444 def is_gmt?
[80]445 @sign == "+1" and @hour == 0 and @minute == 0
[79]446 end
[124]447
[79]448 def as_string
[80]449 if @sign == "+1"
450 s = "+"
451 elsif @sign == "-1"
452 s = "-"
453 end
454 sprintf("Z%s%02d%02d", s, @hour, @minute)
[79]455 end
456 end # end of ISO8601_TIMEZONE
[123]457
[149]458 module ISO8601_DURATION_MODULE
[126]459 attr_reader :years, :months, :weeks, :days
460 attr_reader :hours, :minutes, :seconds, :fractional_second
461
462 def years=(years)
[128]463 unless years.nil? || years >= 0
[126]464 raise ArgumentError, 'years must be above zero'
465 end
466 @years = years
467 end
[124]468
[126]469 def months=(months)
[128]470 unless months.nil? || months >= 0
[126]471 raise ArgumentError, 'months must be above zero'
472 end
473 @months = months
[124]474 end
[126]475
476 def weeks=(weeks)
[128]477 unless weeks.nil? || weeks >= 0
[126]478 raise ArgumentError, 'weeks must be above zero'
479 end
480 @weeks = weeks
481 end
482
483 def days=(days)
[128]484 unless days.nil? || days >= 0
[126]485 raise ArgumentError, 'days must be above zero'
486 end
487 @days = days
488 end
489
490 def hours=(hours)
[128]491 unless hours.nil? || hours >= 0
[126]492 raise ArgumentError, 'hours must be above zero'
493 end
494 @hours = hours
495 end
496
497 def minutes=(minutes)
[128]498 unless minutes.nil? || minutes >= 0
[126]499 raise ArgumentError, 'minutes must be above zero'
500 end
501 @minutes = minutes
502 end
503
504 def seconds=(seconds)
[128]505 unless seconds.nil? || seconds >= 0
[126]506 raise ArgumentError, 'seconds must be above zero'
507 end
508 @seconds = seconds
509 end
510
511 def fractional_second=(fractional_second)
[128]512 unless fractional_second.nil? || (fractional_second >= 0 && fractional_second < 1.0)
[126]513 raise ArgumentError, 'fractional_second must be between 0.0 and 1.0'
514 end
515 @fractional_second = fractional_second
516 end
517
518 def as_string
519 str = 'P'
520 unless @years.nil?
521 str += @years.to_s + 'Y'
522 end
523 unless @months.nil?
524 str += @months.to_s + 'M'
525 end
526 unless @weeks.nil?
527 str += @weeks.to_s + 'W'
528 end
529 unless @days.nil?
530 str += @days.to_s + 'D'
531 end
532 unless @hours.nil?
533 str += 'T' + @hours.to_s + 'H'
534 unless @minutes.nil?
535 str += @minutes.to_s + 'M'
536 unless @seconds.nil?
537 str += @seconds.to_s
538 unless @fractional_second.nil?
539 str += @fractional_second.to_s[1 .. -1]
540 end
541 str += 'S'
542 end
543 end
544 end
545 return str
546 end
[149]547 end
548 class ISO8601_DURATION < TIME_DEFINITIONS
549 include ISO8601_DURATION_MODULE
550 def initialize(str)
551 /^P((\d+)Y)?((\d+)M)?((\d+)W)?((\d)D)?(T((\d+)H)?((\d+)M)?((\d+)(\.\d+)?S)?)?$/ =~ str
552 self.years = $2.to_i
553 self.months = $4.to_i
554 self.weeks = $6.to_i
555 self.days = $8.to_i
556 self.hours = $11.to_i
557 self.minutes = $13.to_i
558 self.seconds = $15.to_i
559 self.fractional_second = $16.to_f
560 end
[124]561 end # end of ISO8601_DURATION
[69]562 end # end of Assumed_Types
563end # end of OpenEHR
Note: See TracBrowser for help on using the repository browser.