partial-date 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,9 @@
1
+ h3. 1.1.0 / 2012-05-27
2
+
3
+ * Implemented a 23bit bit store as backing store for date,
4
+ reducing the storage requirements and increasing performance
5
+ of date objects.
6
+
1
7
  h3. 1.0.0 / 2012-05-27
2
8
 
3
9
  * Refactored to use array backing store for element and computed date
@@ -11,6 +11,7 @@ A simple date class that can be used to store partial date values in a single co
11
11
  h2. Features
12
12
 
13
13
  PartialDate::Date uses an 8 digit integer to store year, month and day values. Values for month and day are optional.
14
+ Use @date.value@ to set or persist the date to a persistance store.
14
15
 
15
16
  h2. Examples
16
17
 
@@ -51,8 +52,6 @@ h2. Install
51
52
  h2. TODO
52
53
 
53
54
  # @PartialDate::Date.parse@ method for construction from strings.
54
- # A Hash or Array backing store for date components for better performance.
55
- # Include Comparable
56
55
 
57
56
  h2. Copyright
58
57
 
@@ -1,4 +1,5 @@
1
1
  require 'partial-date/version'
2
2
  require 'partial-date/error'
3
+ require 'partial-date/bits'
3
4
  require 'partial-date/date'
4
5
  require 'date'
@@ -0,0 +1,52 @@
1
+ module PartialDate
2
+
3
+ class Bits
4
+
5
+ # Key:
6
+ # The firt 5 bits are the day (max 31)
7
+ # The next 4 bits are the month (max 12)
8
+ # The topmost/leftmost 14 bits are the year (max 9999)
9
+
10
+ DAY_MASK = 0b00000000000000000011111
11
+ MONTH_MASK = 0b00000000000000111100000
12
+ YEAR_MASK = 0b11111111111111000000000
13
+
14
+ ZERO_YEAR_MASK = 0b00000000000000111111111
15
+ ZERO_MONTH_MASK = 0b11111111111111000011111
16
+ ZERO_DAY_MASK = 0b111111111111111111000000
17
+
18
+ def self.get_date(register)
19
+ (get_year(register) * 10000) + (get_month(register) * 100) + get_day(register)
20
+ end
21
+
22
+ def self.set_date(register, value)
23
+ register = set_year(register, (value / 10000).abs)
24
+ register = set_month(register, ((value - (value / 10000).abs * 10000) / 100).abs)
25
+ register = set_day(register, value - (value / 100).abs * 100)
26
+ end
27
+
28
+ def self.get_year(register)
29
+ (register & YEAR_MASK) >> 9
30
+ end
31
+
32
+ def self.set_year(register, value)
33
+ register = (register & ZERO_YEAR_MASK) | (value << 9)
34
+ end
35
+
36
+ def self.get_month(register)
37
+ (register & MONTH_MASK) >> 5
38
+ end
39
+
40
+ def self.set_month(register, value)
41
+ register = (register & ZERO_MONTH_MASK) | (value << 5)
42
+ end
43
+
44
+ def self.get_day(register)
45
+ register & DAY_MASK
46
+ end
47
+
48
+ def self.set_day(register, value)
49
+ register = (register & ZERO_DAY_MASK) | value
50
+ end
51
+ end
52
+ end
@@ -36,10 +36,33 @@ module PartialDate
36
36
  #
37
37
  # Returns a date object.
38
38
  def initialize
39
- @data = [0,0,0,0]
39
+ @bits = 0
40
40
  yield self if block_given?
41
41
  end
42
42
 
43
+ # Public: Loads an 8 digit date value into a date object. Can be used
44
+ # when rehydrating a date object from a persisted partial date value.
45
+ #
46
+ # value - an 8 digit value in partial date format.
47
+ #
48
+ # Examples
49
+ #
50
+ # date = PartialDate::Date.load 201212201
51
+ # date.value
52
+ # # => 20120000
53
+ # date.year
54
+ # # => 2012
55
+ # date.month
56
+ # # => 12
57
+ # date.day
58
+ # # => 0
59
+ #
60
+ # Returns date object
61
+ def self.load(value)
62
+ PartialDate::Date.new {|d| d.value = value}
63
+ end
64
+
65
+
43
66
  # Public: Get the integer date value in partial date format.
44
67
  #
45
68
  # Examples
@@ -50,7 +73,7 @@ module PartialDate
50
73
  #
51
74
  # Returns an integer representation of a partial date.
52
75
  def value
53
- get_value(0)
76
+ Bits.get_date(@bits)
54
77
  end
55
78
 
56
79
  # Public: Set a date value using an interger in partial date format.
@@ -62,34 +85,12 @@ module PartialDate
62
85
  # Returns nothing
63
86
  def value=(value)
64
87
  if value.is_a?(Integer) && (value >= 10000 && value <= 99991231)
65
- set_value(0, value)
88
+ @bits = Bits.set_date(@bits, value)
66
89
  else
67
90
  raise PartialDateError, "Date value must be an integer betwen 10000 and 99991231"
68
91
  end
69
92
  end
70
93
 
71
- # Public: Loads an 8 digit date value into a date object. Can be used
72
- # when rehydrating a date object from a persisted partial date value.
73
- #
74
- # value - an 8 digit value in partial date format.
75
- #
76
- # Examples
77
- #
78
- # date = PartialDate::Date.load 201212201
79
- # date.value
80
- # # => 20120000
81
- # date.year
82
- # # => 2012
83
- # date.month
84
- # # => 12
85
- # date.day
86
- # # => 0
87
- #
88
- # Returns date object
89
- def self.load(value)
90
- PartialDate::Date.new {|d| d.value = value}
91
- end
92
-
93
94
 
94
95
  # Public: Sets the year portion of a partial date.
95
96
  #
@@ -116,7 +117,7 @@ module PartialDate
116
117
  end
117
118
 
118
119
  if value.is_a?(Integer) && (value <= 9999 && value > 0)
119
- set_value(1, value)
120
+ @bits = Bits.set_year(@bits, value)
120
121
  else
121
122
  raise PartialDateError, "Year must be an integer between 1 and 9999"
122
123
  end
@@ -124,7 +125,7 @@ module PartialDate
124
125
 
125
126
  # Public: Get the year from a partial date.
126
127
  def year
127
- get_value(1)
128
+ Bits.get_year(@bits)
128
129
  end
129
130
 
130
131
  # Public: Set the month of a partial date.
@@ -143,7 +144,7 @@ module PartialDate
143
144
  end
144
145
 
145
146
  if value.is_a?(Integer) && (value <= 12 && value >= 0)
146
- set_value(2, value)
147
+ @bits = Bits.set_month(@bits, value)
147
148
  else
148
149
  raise PartialDateError, "Month must an be integer between 1 and 12"
149
150
  end
@@ -151,7 +152,7 @@ module PartialDate
151
152
 
152
153
  # Public: Get the month from a partial date.
153
154
  def month
154
- get_value(2)
155
+ Bits.get_month(@bits)
155
156
  end
156
157
 
157
158
 
@@ -174,8 +175,7 @@ module PartialDate
174
175
  if value.is_a?(Integer) && (value >= 0 && value <= 31)
175
176
  begin
176
177
  date = ::Date.civil(self.year, self.month, value) if value > 0
177
- #@value = (self.value - self.day + value)
178
- set_value(3, value)
178
+ @bits = Bits.set_day(@bits, value)
179
179
  rescue
180
180
  raise PartialDateError, "Day must be a valid day for the given month"
181
181
  end
@@ -186,8 +186,7 @@ module PartialDate
186
186
 
187
187
  # Public: Get the day from a partial date.
188
188
  def day
189
- #self.value > 0 ? self.value - (self.value / 100).abs * 100 : 0
190
- get_value(3)
189
+ Bits.get_day(@bits)
191
190
  end
192
191
 
193
192
  # Public: Returns a formatted string representation of the partial date.
@@ -216,39 +215,5 @@ module PartialDate
216
215
  def <=>(other_date)
217
216
  self.value <=> other_date.value
218
217
  end
219
-
220
-
221
- private
222
-
223
- # Internal: Retreive a value from the array backing store.
224
- #
225
- # Returns an integer value for partial date, year, month or day.
226
- def get_value(element)
227
- @data[element]
228
- end
229
-
230
- # Internal: Set a value in the array backing store - either the
231
- # complete date value (from load or value accessors), or a year,
232
- # month, or day value after which the partial date will be recomputed.
233
- #
234
- # Returns nothing
235
- def set_value(element, value)
236
- case element
237
- when 0
238
- @data[1] = (value / 10000).abs
239
- @data[2] = ((value - (value / 10000).abs * 10000) / 100).abs
240
- @data[3] = value - (value / 100).abs * 100
241
- when 1
242
- @data[0] = @data[0] - (self.year * 10000) + (value * 10000)
243
- when 2
244
- @data[0] = @data[0] - (self.month * 100) + (value * 100)
245
- when 3
246
- @data[0] = @data[0] - self.day + value
247
- end
248
-
249
- # Important - update the old element value _after_ @data[0]
250
- # has been recalculated above.
251
- @data[element] = value
252
- end
253
218
  end
254
219
  end
@@ -1,4 +1,4 @@
1
1
  module PartialDate
2
2
  # partial-date version
3
- VERSION = "1.0.0"
3
+ VERSION = "1.1.0"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: partial-date
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -78,6 +78,7 @@ files:
78
78
  - README.textile
79
79
  - Rakefile
80
80
  - lib/partial-date.rb
81
+ - lib/partial-date/bits.rb
81
82
  - lib/partial-date/date.rb
82
83
  - lib/partial-date/error.rb
83
84
  - lib/partial-date/version.rb