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.
- 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
|