partial-date 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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