source: ruby/branches/0.5.0/lib/open_ehr/rm/data_types/quantity/date_time.rb@ 167

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

adjust for rails

File size: 8.9 KB
RevLine 
[88]1# This module is implementation of the UML:
2# http://www.openehr.org/uml/release-1.0.1/Browsable/_9_0_76d0249_1109696321450_28117_5362Report.html
3# Ticket refs #49
[149]4require 'assumed_library_types'
[151]5require 'date'
[149]6
[167]7module OpenEhr
[4]8 module RM
[167]9 module DataTypes
[4]10 module Quantity
[167]11 module DateTime
12 class DvTemporal < OpenEhr::RM::DataTypes::Quantity::DvAbsoluteQuantity
[157]13 include Comparable
[120]14 attr_reader :value
[123]15
[149]16 def initialize(value, magnitude_status=nil, accuracy=nil,
17 normal_range=nil, normal_status=nil,
18 other_reference_ranges=nil)
[120]19 self.value = value
[149]20 self.magnitude_status = magnitude_status
21 self.accuracy = accuracy
22 self.normal_range = normal_range
23 self.normal_status = normal_status
24 self.other_reference_ranges = other_reference_ranges
[120]25 end
[123]26
[120]27 def value=(value)
[149]28 if value.nil? or value.empty?
[120]29 raise ArgumentError, 'invalid value'
30 end
31 @value = value
32 end
[157]33
34 def <=>(other)
35 self.magnitude <=> other.magnitude
36 end
[120]37 end
38
[167]39 class DvDate < DvTemporal
40 include OpenEhr::AssumedLibraryTypes::ISO8601_DATE_MODULE
[149]41
42 DAYS_IN_MONTH = [0,31,28,31,30,31,30,31,31,30,31,30,31]
43
44 def initialize(value, magnitude_status=nil, accuracy=nil,
45 normal_range=nil, normal_status=nil,
46 other_reference_range=nil)
47 super(value, magnitude_status, accuracy, normal_range,
48 normal_status, other_reference_range)
[120]49 end
[123]50
[149]51 def value=(value)
52 super(value)
[167]53 iso8601_date = AssumedLibraryTypes::ISO8601_DATE.new(value)
[149]54 @year = iso8601_date.year
55 @month = iso8601_date.month
56 @day = iso8601_date.day
57 end
58
59 undef magnitude=
60
61 def magnitude
[150]62 return Date.new(@year, @month, @day)-Date.new(0000,1,1)
[149]63 end
64
65 def diff(other)
66 if self.magnitude > other.magnitude
67 past, future = other, self
68 else
69 past, future = self, other
70 end
71 year, month, day = 0, 0, 0
72 if (future.day >= past.day)
73 day = future.day - past.day
74 else
75 month -= 1
76 previous_month = future.month - 1
77 if previous_month <= 0
78 previous_month = 12
79 end
80 day = DAYS_IN_MONTH[previous_month] + future.day - past.day
81 if leapyear?(future.year) && (previous_month == 2)
82 day += 1
83 end
84 end
85 week = day / 7
86 if (future.month >= past.month)
87 month += future.month - past.month
88 else
89 year -= 1
90 month += future.month + 12 - past.month
91 end
92 year += future.year - past.year
[167]93 return DvDuration.new(
[149]94 'P' + year.to_s + 'Y' + month.to_s + 'M' +
95 week.to_s + 'W' + day.to_s + 'D')
96 end
[88]97 end
[123]98
[167]99 class DvTime < DvTemporal
100 include OpenEhr::AssumedLibraryTypes::ISO8601_TIME_MODULE
[150]101 def initialize(value, magnitude_status=nil, accuracy=nil,
102 normal_range=nil, normal_status=nil,
103 other_reference_range=nil)
104 super(value, magnitude_status, accuracy, normal_range,
105 normal_status, other_reference_range)
[123]106 end
[150]107
108 def value=(value)
109 super(value)
[167]110 iso8601_time = AssumedLibraryTypes::ISO8601_TIME.new(value)
[150]111 @hour = iso8601_time.hour
112 @minute = iso8601_time.minute
113 @second = iso8601_time.second
114 @fractional_second = iso8601_time.fractional_second
115 end
116
117 def magnitude
118 return @hour * 60 * 60 + @minute * 60 + @second + @fractional_second
119 end
120
121 def diff(other)
122 diff = (other.magnitude - self.magnitude).abs
123 hour = (diff / 60 / 60).to_i
124 minute = ((diff - hour*60*60)/60).to_i
125 second = (diff - hour * 60 *60 - minute * 60).to_i
[151]126 fractional_second = ((diff - diff.to_i)*1000000.0).to_i/1000000.0
[167]127 return DvDuration.new('P0Y0M0W0DT' + hour.to_s + 'H' +
[151]128 minute.to_s + 'M' +
129 second.to_s + fractional_second.to_s[1..-1] + 'S')
[150]130 end
[123]131 end
132
[167]133 class DvDateTime < DvTemporal
134 include OpenEhr::AssumedLibraryTypes::ISO8601_DATE_TIME_MODULE
[151]135 attr_reader :value
136
137 def initialize(value, magnitude_status=nil, accuracy=nil,
138 normal_range=nil, normal_status=nil,
139 other_reference_range=nil)
140 super(value, magnitude_status, accuracy, normal_range,
141 normal_status, other_reference_range)
[123]142 end
[151]143
144 def value=(value)
145 super(value)
[167]146 iso8601date_time = AssumedLibraryTypes::ISO8601_DATE_TIME.new(value)
[151]147 self.year = iso8601date_time.year
148 self.month = iso8601date_time.month
149 self.day = iso8601date_time.day
150 self.minute = iso8601date_time.minute
151 self.second = iso8601date_time.second
152 self.hour = iso8601date_time.hour
153 self.fractional_second = iso8601date_time.fractional_second
154 self.timezone = iso8601date_time.timezone
155 end
156
157 def magnitude
[157]158 seconds = DateTime.new(@year,@month,@day,@hour,@minute,@second) -
159 DateTime.new(0000,1,1,0,0,0)
160 if @fractional_second.nil?
161 return seconds
162 else
163 return seconds + @fractional_second
164 end
[151]165 end
166
167 undef magnitude=
168
169 def diff(other)
170 if self.magnitude >= other.magnitude
171 past, future = other, self
172 else
173 past, future = self, other
174 end
175 past_date, past_time = split_date_time(past)
176 future_date, future_time = split_date_time(future)
177 time_diff = future_time.magnitude - past_time.magnitude
178 if future_time.magnitude < past_time.magnitude
179 future_date.day = future_date.day - 1
180 time_diff += 24 * 60 * 60
181 end
182 date_duration = past_date.diff(future_date)
183 hour = (time_diff / 60 / 60).to_i
184 minute = ((time_diff - hour*60*60)/60).to_i
185 second = (time_diff - hour * 60 *60 - minute * 60).to_i
186 fractional_second = ((time_diff - time_diff.to_i)*1000000.0).to_i/1000000.0
187
[167]188 return DvDuration.new(date_duration.value + 'T' +
[151]189 hour.to_s + 'H' +
190 minute.to_s + 'M' +
191 second.to_s + fractional_second.to_s[1..-1] + 'S')
192
193 end
194
195 private
196
197 def split_date_time(date_time)
198 /^(.*)T(.*)$/ =~ date_time.as_string
[167]199 return DvDate.new($1), DvTime.new($2)
[151]200 end
[123]201 end
[149]202
[167]203 class DvDuration < DvAmount
204 include AssumedLibraryTypes::ISO8601_DURATION_MODULE
[149]205 attr_reader :value
206
207 def initialize(value, magnitude_status=nil, accuracy=nil,
208 accuracy_percent=nil, normal_range=nil,
209 normal_status = nil, other_reference_ranges=nil)
210 self.value = value
211 end
212
213 def value=(value)
214 raise ArgumentError, 'value must be not nil' if value.nil?
215 @value = value
[167]216 iso8601_duration = AssumedLibraryTypes::ISO8601_DURATION.new(value)
[149]217 self.years = iso8601_duration.years
218 self.months = iso8601_duration.months
219 self.weeks = iso8601_duration.weeks
220 self.days = iso8601_duration.days
221 self.hours = iso8601_duration.hours
222 self.minutes = iso8601_duration.minutes
223 self.seconds = iso8601_duration.seconds
224 self.fractional_second = iso8601_duration.fractional_second
225 end
226
227 def magnitude
228 return ((((@year + @month/MONTH_IN_YEAR)*NOMINAL_DAYS_IN_MONTH) +
229 @week * DAYS_IN_WEEK + @days) * HOURS_IN_DAY * MINUTES_IN_HOUR*
230 SECONDS_IN_MINUTE) + @second + @fractional_second
231 end
232
233 undef magnitude=
234
235 end
[167]236 end # of DateTime
[4]237 end # of Quantity
238 end # of Data_Types
239 end # of RM
240end # of OpenEHR
Note: See TracBrowser for help on using the repository browser.