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

Last change on this file since 112 was 83, checked in by KOBAYASHI, Shinji, 16 years ago

refs #36
almost all fixed ISO8601_TIME

File size: 8.5 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 class ISO8601_DATE < TIME_DEFINITIONS
112 attr_reader :year, :month, :day
113 def initialize(year = nil, month = nil, day = nil)
114 @year = @month = @day = nil
115 if !year.nil?
116 self.year = year
117 end
118 if !month.nil?
119 self.month = month
120 end
121 if !day.nil?
122 self.day = day
123 end
124 end
125 def year=(year)
126 raise ArgumentError, "Year is not valid" if !ISO8601_DATE.valid_year?(year)
127 @year = year
128 end
129 def month=(month)
130 raise ArgumentError, "Month is not valid" if !ISO8601_DATE.valid_month?(month)
131 @month = month
132 end
133 def day=(day)
134 raise ArgumentError, "Day is not valid" if !ISO8601_DATE.valid_day?(@year, @month, day)
135 @day = day
136 end
137 def as_string
138 if (!@year.nil? and !@month.nil? and !@day.nil?)
139 Date.new(@year, @month, @day).to_s
140 elsif (!@year.nil? and !@month.nil? and @day.nil?)
141 Date.new(@year, @month).to_s[0,7]
142 elsif (!@year.nil? and @month.nil? and @day.nil?)
143 Date.new(@year).to_s[0,4]
144 end
145 end
146 def month_unknown?
147 @month.nil?
148 end
149 def day_unknown?
150 @day.nil?
151 end
152 def is_extended?
153 true
154 end
155 def is_partial?
156 month_unknown? or day_unknown?
157 end
158 def self.valid_iso8601_date?(string)
159 begin
160 Date.parse(string)
161 rescue
162 return false
163 end
164 true
165 end
166
167 end # end of ISO8601_DATE
168
169 class ISO8601_TIME < TIME_DEFINITIONS
170 attr_reader :hour, :minute, :second, :fractional_second, :timezone
171 def initialize(hh, mm = nil, ss = nil, msec = nil, tz = nil)
172 raise ArgumentError, "Not valid hour format" if !ISO8601_TIME.valid_hour?(hh,mm,ss)
173 @hour = hh; @minute = mm; @second = ss
174 @fractional_second = msec; @timezone = tz
175 end
176 def hour=(hour)
177 raise ArgumentError, "hour is not valid" if !ISO8601_TIME.valid_hour?(hour, @minute, @second)
178 @hour = hour
179 end
180 def minute_unknown?
181 @minute.nil?
182 end
183 def minute=(minute)
184 raise ArgumentError, "minute is not valid" if !minute.nil? and !ISO8601_TIME.valid_minute?(minute)
185 @minute = minute
186 end
187 def second_unknown?
188 @second.nil?
189 end
190 def second=(second)
191 raise ArgumentError, "minute not defined" if @minute.nil?
192 raise ArgumentError, "second is not valid" if !second.nil? and !ISO8601_TIME.valid_second?(second)
193 @second = second
194 end
195 def fractional_second=(fractional_second)
196 raise ArgumentError, "minute not defined" if minute_unknown?
197 raise ArgumentError, "second not defined" if second_unknown?
198 raise ArgumentError, "fractional second should be lower than 1.0" if fractional_second >= 1.0
199 @fractional_second = fractional_second
200 end
201 def has_fractional_second?
202 if @fractional_second.nil?
203 return false
204 else
205 return true
206 end
207 end
208 def is_decimal_sign_comma?
209 true
210 end
211 def is_extended?
212 true
213 end
214 def is_partial?
215 second_unknown? or minute_unknown?
216 end
217 def as_string
218 s = sprintf("%02d", @hour)
219 if !@minute.nil?
220 s += ":" + sprintf("%02d",@minute)
221 if !@second.nil?
222 s += ":" + sprintf("%02d", @second)
223 if !@fractional_second.nil?
224 s += "," + @fractional_second.to_s[2..-1]
225 if !@timezone.nil?
226 s += @timezone
227 end
228 end
229 end
230 end
231 s
232 end
233 def self.valid_iso8601_time?(s)
234 if /(\d{2}):?(\d{2})?(:?)(\d{2})?((\.|,)(\d+))?(Z|([+-](\d{2}):?(\d{2})))?/ =~ s
235# ISO 8601 regular expression by H. Yuki
236# 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
237# (\d{4})(?:-(\d{2})(?:-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d))?)?(Z|([+-]\d{2}):(\d{2}))?)?)?)?
238 hh = $1; mm = $2; ss = $4; msec = $7; tz = $8
239 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)
240 return true
241 end
242 if hh.nil? or (hh.to_i < 0 or hh.to_i >= HOURS_IN_DAY)
243 return false
244 end
245 if !mm.nil?
246 if !self.valid_minute?(mm.to_i)
247 return false
248 end
249 end
250 if !ss.nil?
251 if !self.valid_second?(ss.to_i)
252 return false
253 end
254 end
255 if !tz.nil? and tz != "Z"
256 if /[+-](\d{2}):?(\d{2})/ =~ tz
257 h = $1; m = $2
258 if h.to_i < 0 or h.to_i >= HOURS_IN_DAY
259 return false
260 end
261 if m.to_i < 0 or m.to_i >= MINUTES_IN_HOUR
262 return false
263 end
264 else
265 return false
266 end
267 end
268 return true
269 else
270 return false
271 end
272 end
273 end # end of ISO8601_TIME
274
275 class ISO8601_TIMEZONE
276 attr_accessor :sign, :hour, :minute
277 def is_gmt?
278 @sign == "+1" and @hour == 0 and @minute == 0
279 end
280 def as_string
281 if @sign == "+1"
282 s = "+"
283 elsif @sign == "-1"
284 s = "-"
285 end
286 sprintf("Z%s%02d%02d", s, @hour, @minute)
287 end
288 end # end of ISO8601_TIMEZONE
289 end # end of Assumed_Types
290end # end of OpenEHR
Note: See TracBrowser for help on using the repository browser.