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.
- data/ChangeLog.textile +6 -0
- data/README.textile +1 -2
- data/lib/partial-date.rb +1 -0
- data/lib/partial-date/bits.rb +52 -0
- data/lib/partial-date/date.rb +32 -67
- data/lib/partial-date/version.rb +1 -1
- metadata +2 -1
data/ChangeLog.textile
CHANGED
@@ -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
|
data/README.textile
CHANGED
@@ -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
|
|
data/lib/partial-date.rb
CHANGED
@@ -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
|
data/lib/partial-date/date.rb
CHANGED
@@ -36,10 +36,33 @@ module PartialDate
|
|
36
36
|
#
|
37
37
|
# Returns a date object.
|
38
38
|
def initialize
|
39
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/partial-date/version.rb
CHANGED
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.
|
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
|