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

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

refs #36, #49

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