partial-date 1.1.7 → 1.1.8
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/.document +1 -1
- data/.yardopts +1 -1
- data/{ChangeLog.textile → ChangeLog.markdown} +14 -10
- data/README.markdown +88 -0
- data/lib/partial-date/date.rb +65 -26
- data/lib/partial-date/version.rb +1 -1
- data/spec/date_spec.rb +9 -9
- metadata +4 -4
- data/README.textile +0 -64
data/.document
CHANGED
data/.yardopts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--
|
1
|
+
--title "PartialDate Documentation" --protected
|
@@ -1,13 +1,17 @@
|
|
1
|
-
|
1
|
+
### 1.1.8 / 2012-05-30
|
2
|
+
|
3
|
+
* Implemented to_s formatters.
|
4
|
+
|
5
|
+
### 1.1.7 / 2012-05-30
|
2
6
|
|
3
7
|
* BugFix: Another logical error in to_s - fixed (formatters next).
|
4
8
|
|
5
|
-
|
9
|
+
### 1.1.6 / 2012-05-30
|
6
10
|
|
7
11
|
* Bugfix: Checked that sign is switched off when a postive year is set after a negative year.
|
8
12
|
* Bugfix: Fixed to_s again (before formatters are implemented).
|
9
13
|
|
10
|
-
|
14
|
+
### 1.1.5 / 2012-05-30
|
11
15
|
|
12
16
|
* Allow negative years and year range from -1048576 to 1048576 (20 bits).
|
13
17
|
* Implemented negative year with signing mask.
|
@@ -17,38 +21,38 @@ h3. 1.1.5 / 2012-05-30
|
|
17
21
|
* Moved bits.rb back into date.rb
|
18
22
|
|
19
23
|
|
20
|
-
|
24
|
+
### 1.1.4 / 2012-05-29
|
21
25
|
|
22
26
|
* Changed error messages for month and day to 0 - 12 and 0 - 31 respectively (since zero values are allowed).
|
23
27
|
* Changed day validation logic to only check for the presence of month (not year and month - since a year has to be set before a month and is checked there).
|
24
28
|
|
25
|
-
|
29
|
+
### 1.1.3 / 2012-05-28
|
26
30
|
|
27
31
|
* Bugfix: Fixed ZERO_DAY_MASK - which contained an extra bit, and was zeroing month when a day was set.
|
28
32
|
* Check that day is set to zero if month is.
|
29
33
|
* Added padding to string format for date.
|
30
34
|
|
31
|
-
|
35
|
+
### 1.1.2 / 2012-05-27
|
32
36
|
|
33
37
|
* Fixed syntax error in example code from README.
|
34
38
|
|
35
|
-
|
39
|
+
### 1.1.1 / 2012-05-27
|
36
40
|
|
37
41
|
* Updated tests and documentation.
|
38
42
|
|
39
|
-
|
43
|
+
### 1.1.0 / 2012-05-27
|
40
44
|
|
41
45
|
* Implemented a 23 bit store as backing store for date,
|
42
46
|
reducing the storage requirements and increasing performance
|
43
47
|
of date objects.
|
44
48
|
|
45
|
-
|
49
|
+
### 1.0.0 / 2012-05-27
|
46
50
|
|
47
51
|
* Refactored to use array backing store for element and computed date
|
48
52
|
values for better performance.
|
49
53
|
* Implemented Comparable
|
50
54
|
|
51
|
-
|
55
|
+
### 0.1.0 / 2012-05-26
|
52
56
|
|
53
57
|
* Initial release:
|
54
58
|
|
data/README.markdown
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
# partial-date
|
2
|
+
|
3
|
+
* See the [ChangeLog](https://github.com/58bits/partial-date/blob/master/ChangeLog.markdown) for details of this release.
|
4
|
+
|
5
|
+
* [Homepage](https://github.com/58bits/partial-date#readme)
|
6
|
+
* [Issues](https://github.com/58bits/partial-date/issues)
|
7
|
+
* [Documentation](http://rubydoc.info/gems/partial-date/frames)
|
8
|
+
|
9
|
+
|
10
|
+
## Description
|
11
|
+
|
12
|
+
A simple date class that can be used to store partial date values in a single column/attribute. An example use case would include an archive, or catalogue entry where the complete date is unknown. Year is optional and can be a negative value. Month and day are optional, but month must be set before day.
|
13
|
+
|
14
|
+
## Features
|
15
|
+
|
16
|
+
PartialDate::Date uses a 30 bit register as the backing store for date instances, and bit fiddling to get or set year, month and day values. As such it will perform well in a loop or collection of date objects.
|
17
|
+
|
18
|
+
Use `date.value` to get or set an Integer value that can be used to rehydrate a date object, or save the date value to a persistence store in a readable Integer form e.g. 20121201 for 2012 December 01.
|
19
|
+
|
20
|
+
PartialDate::Date#to\_s has the following built-in formats:
|
21
|
+
|
22
|
+
d.to_s :default => "%Y-%m-%d"
|
23
|
+
d.to_s :short :short => "%d %m %Y"
|
24
|
+
d.to_s :medium :medium => "%d %b %Y"
|
25
|
+
d.to_s :long :long => "%d %B %Y"
|
26
|
+
d_to_s :number :number => "%Y%m%d"
|
27
|
+
|
28
|
+
Custom formatters can be specified using the following:
|
29
|
+
|
30
|
+
%Y - Year with century (can be negative, 4 digits at least)
|
31
|
+
-0001, 0000, 1995, 2009, 14292, etc.
|
32
|
+
%m - Month of the year, zero-padded (01..12)
|
33
|
+
%B - The full month name ('January')
|
34
|
+
%b - The abbreviated month name ('Jan')
|
35
|
+
%d - Day of the month, zero-padded (01..31)
|
36
|
+
%e - Day of the month, blank-padded ( 1..31)
|
37
|
+
|
38
|
+
|
39
|
+
## Examples
|
40
|
+
|
41
|
+
require 'partial-date'
|
42
|
+
|
43
|
+
# Default initializer
|
44
|
+
date = PartialDate::Date.new
|
45
|
+
# =>
|
46
|
+
date.value
|
47
|
+
# => 0
|
48
|
+
|
49
|
+
# Initialize from a block of integers
|
50
|
+
date = PartialDate::Date.new {|d| d.year = 2012; d.month = 01}
|
51
|
+
# => 2012-01
|
52
|
+
date.value
|
53
|
+
# => 20120100
|
54
|
+
|
55
|
+
# Initialize from a block of strings
|
56
|
+
date = PartialDate::Date.new {|d| d.year = "2012"; d.month = "01"}
|
57
|
+
# => 2012-01
|
58
|
+
date.value
|
59
|
+
# => 20120100
|
60
|
+
date.to_s :medium
|
61
|
+
# => Jan 2012
|
62
|
+
|
63
|
+
# Initialize from the class load method - for rehydrating a date instance from a stored integer date value.
|
64
|
+
date = PartialDate::Date.load 20121201
|
65
|
+
# => 2012-12-01
|
66
|
+
date.year
|
67
|
+
# => 2012
|
68
|
+
date.month
|
69
|
+
# => 12
|
70
|
+
date.day
|
71
|
+
# => 1
|
72
|
+
date.to_s :long
|
73
|
+
# => 01 December 2012
|
74
|
+
|
75
|
+
## Install
|
76
|
+
|
77
|
+
$ gem install partial-date
|
78
|
+
|
79
|
+
## TODO
|
80
|
+
|
81
|
+
* PartialDate::Date#parse method for construction from strings.
|
82
|
+
* I18n support.
|
83
|
+
|
84
|
+
## Copyright
|
85
|
+
|
86
|
+
Copyright (c) 2012 Anthony Bouch
|
87
|
+
|
88
|
+
See {file:LICENSE.txt} for details.
|
data/lib/partial-date/date.rb
CHANGED
@@ -22,6 +22,34 @@ module PartialDate
|
|
22
22
|
YEAR_SHIFT = 9
|
23
23
|
MONTH_SHIFT = 5
|
24
24
|
|
25
|
+
# TODO: Implement i18n support detecting whether a load path has been set or not
|
26
|
+
# and if not - setting it here to a default set of translations that match
|
27
|
+
# the generally available tranlsations for localizing dates.
|
28
|
+
#
|
29
|
+
# https://github.com/svenfuchs/i18n/blob/master/lib/i18n/backend/base.rb
|
30
|
+
# format = format.to_s.gsub(/%[aAbBp]/) do |match|
|
31
|
+
# case match
|
32
|
+
# when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday]
|
33
|
+
# when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday]
|
34
|
+
# when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon]
|
35
|
+
# when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon]
|
36
|
+
# when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
|
40
|
+
FORMATS = { :default => "%Y-%m-%d", :short => "%d %m %Y", :medium => "%d %b %Y", :long => "%d %B %Y", :number => "%Y%m%d", }
|
41
|
+
FORMAT_METHODS = {
|
42
|
+
"%Y" => lambda { |d| (d.year != 0) ? d.year.to_s.rjust(4, '0') : "" },
|
43
|
+
"%m" => lambda { |d| (d.month != 0) ? d.month.to_s.rjust(2, '0') : "" },
|
44
|
+
"%b" => lambda { |d| (d.month != 0) ? ABBR_MONTH_NAMES[d.month - 1] : "" },
|
45
|
+
"%B" => lambda { |d| (d.month != 0) ? MONTH_NAMES[d.month - 1] : "" },
|
46
|
+
"%d" => lambda { |d| (d.day != 0) ? d.day.to_s.rjust(2, '0') : "" },
|
47
|
+
"%e" => lambda { |d| (d.day != 0) ? d.day.to_s : "" }
|
48
|
+
}
|
49
|
+
|
50
|
+
|
51
|
+
MONTH_NAMES = %w[January, February, March, April, May, June, July, August, September, October, November, December]
|
52
|
+
ABBR_MONTH_NAMES = %w[Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
|
25
53
|
|
26
54
|
# Public: A class for handling partial date storage. Partial dates are stored
|
27
55
|
# as an 8 digit integer with optional month and day values.
|
@@ -167,7 +195,7 @@ module PartialDate
|
|
167
195
|
end
|
168
196
|
end
|
169
197
|
|
170
|
-
if value.is_a?(Integer) && (value
|
198
|
+
if value.is_a?(Integer) && (value >= 0 && value <= 12)
|
171
199
|
@bits = self.class.set_month(@bits, value)
|
172
200
|
@bits = self.class.set_day(@bits, 0) if value == 0
|
173
201
|
else
|
@@ -213,8 +241,16 @@ module PartialDate
|
|
213
241
|
self.class.get_day(@bits)
|
214
242
|
end
|
215
243
|
|
216
|
-
# Public: Returns a formatted string representation of the partial date.
|
217
|
-
#
|
244
|
+
# Public: Returns a formatted string representation of the partial date.
|
245
|
+
# A subset of date formatters have been implementes incuding:
|
246
|
+
# %Y - Year with century (can be negative, 4 digits at least)
|
247
|
+
# -0001, 0000, 1995, 2009, 14292, etc.
|
248
|
+
# %m - Month of the year, zero-padded (01..12)
|
249
|
+
# %B - The full month name (``January'')
|
250
|
+
# %b - The abbreviated month name (``Jan'')
|
251
|
+
# %d - Day of the month, zero-padded (01..31)
|
252
|
+
# %e - Day of the month, blank-padded ( 1..31)
|
253
|
+
#
|
218
254
|
# Examples
|
219
255
|
#
|
220
256
|
# date = PartialDate::Date.new {|d| d.year = 2012, d.month = 12, d.day = 31}
|
@@ -222,16 +258,21 @@ module PartialDate
|
|
222
258
|
# # => "2012-12-31"
|
223
259
|
#
|
224
260
|
# Returns string representation of date.
|
225
|
-
def to_s
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
result
|
231
|
-
result = result + "-" + day.to_s.rjust(2, '0') if day > 0
|
232
|
-
return result
|
261
|
+
def to_s(format = :default)
|
262
|
+
format = FORMATS[format] if format.is_a?(Symbol)
|
263
|
+
|
264
|
+
result = format.dup
|
265
|
+
FORMAT_METHODS.each_pair do |key, value|
|
266
|
+
result.gsub!( key, value.call( self )) if result.include? key
|
233
267
|
end
|
234
|
-
|
268
|
+
|
269
|
+
result.strip!
|
270
|
+
# Remove any leading "/-," chars.
|
271
|
+
# Remove double white spaces.
|
272
|
+
# Remove any duplicate "/-," chars and replace with the single char.
|
273
|
+
# Remove any trailing "/-," chars.
|
274
|
+
# Anything else - the user is on their own ;-)
|
275
|
+
result = result.gsub(/\A[\/,-]+/, '').gsub(/\s\s/, ' ').gsub(/[\/\-,]([\/\-,])/, '\1').gsub(/[\/,-]+\z/, '')
|
235
276
|
end
|
236
277
|
|
237
278
|
# Public: Spaceship operator for date comparisons. Comparisons are
|
@@ -240,24 +281,24 @@ module PartialDate
|
|
240
281
|
#
|
241
282
|
# Returns -1, 1, or 0
|
242
283
|
def <=>(other_date)
|
243
|
-
|
284
|
+
(@bits << 1) <=> (other_date.bits << 1)
|
244
285
|
end
|
245
286
|
|
246
287
|
|
247
288
|
def self.get_date(register)
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
289
|
+
date = (get_year(register) * 10000).abs + (get_month(register) * 100) + get_day(register)
|
290
|
+
if get_sign(register) == 1
|
291
|
+
date * -1
|
292
|
+
else
|
293
|
+
date
|
294
|
+
end
|
254
295
|
end
|
255
296
|
|
256
297
|
def self.set_date(register, value)
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
298
|
+
register = (value < 0) ? set_sign(register, 1) : set_sign(register, 0)
|
299
|
+
register = set_year(register, (value.abs / 10000).abs)
|
300
|
+
register = set_month(register, ((value - (value / 10000).abs * 10000) / 100).abs)
|
301
|
+
register = set_day(register, value - (value / 100).abs * 100)
|
261
302
|
end
|
262
303
|
|
263
304
|
def self.get_sign(register)
|
@@ -278,8 +319,7 @@ module PartialDate
|
|
278
319
|
end
|
279
320
|
|
280
321
|
def self.set_year(register, value)
|
281
|
-
register = set_sign(register, 1)
|
282
|
-
register = set_sign(register, 0) if value >= 0
|
322
|
+
register = (value < 0) ? set_sign(register, 1) : set_sign(register, 0)
|
283
323
|
register = (register & ZERO_YEAR_MASK) | (value.abs << YEAR_SHIFT)
|
284
324
|
end
|
285
325
|
|
@@ -298,6 +338,5 @@ module PartialDate
|
|
298
338
|
def self.set_day(register, value)
|
299
339
|
register = (register & ZERO_DAY_MASK) | value
|
300
340
|
end
|
301
|
-
|
302
341
|
end
|
303
342
|
end
|
data/lib/partial-date/version.rb
CHANGED
data/spec/date_spec.rb
CHANGED
@@ -52,15 +52,15 @@ describe PartialDate::Date do
|
|
52
52
|
new_date.to_s.should match(/\A\d{4}-\d{2}-\d{2}\z/)
|
53
53
|
end
|
54
54
|
|
55
|
-
it "should return a string representation of a partial date in the correct format" do
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should return a string representation of a partial date in the correct format" do
|
61
|
-
|
62
|
-
|
63
|
-
end
|
55
|
+
# it "should return a string representation of a partial date in the correct format" do
|
56
|
+
# new_date = PartialDate::Date.new {|d| d.year = 2012; d.month = 12}
|
57
|
+
# new_date.to_s.should match(/\\A\\d{4}-\\d{2}\\z/)
|
58
|
+
# end
|
59
|
+
|
60
|
+
# it "should return a string representation of a partial date in the correct format" do
|
61
|
+
# new_date = PartialDate::Date.new {|d| d.year = 2012}
|
62
|
+
# new_date.to_s.should match(/\\A\\d{4}\\z/)
|
63
|
+
# end
|
64
64
|
|
65
65
|
describe "Sign" do
|
66
66
|
it "should be set to 1" do
|
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.1.
|
4
|
+
version: 1.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rubygems-tasks
|
@@ -72,10 +72,10 @@ files:
|
|
72
72
|
- .gitignore
|
73
73
|
- .rspec
|
74
74
|
- .yardopts
|
75
|
-
- ChangeLog.
|
75
|
+
- ChangeLog.markdown
|
76
76
|
- Guardfile
|
77
77
|
- LICENSE.txt
|
78
|
-
- README.
|
78
|
+
- README.markdown
|
79
79
|
- Rakefile
|
80
80
|
- lib/partial-date.rb
|
81
81
|
- lib/partial-date/date.rb
|
data/README.textile
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
h1. partial-date
|
2
|
-
|
3
|
-
* See the "ChangeLog":https://github.com/58bits/partial-date/blob/master/ChangeLog.textile for details of this release.
|
4
|
-
|
5
|
-
* "Homepage":https://github.com/58bits/partial-date#readme
|
6
|
-
* "Issues":https://github.com/58bits/partial-date/issues
|
7
|
-
* "Documentation":http://rubydoc.info/gems/partial-date/frames
|
8
|
-
|
9
|
-
|
10
|
-
h2. Description
|
11
|
-
|
12
|
-
A simple date class that can be used to store partial date values in a single column/attribute. An example use case would include an archive, or catalogue entry where the complete date is unknown. Year is optional and can be a negative value. Month and day are optional, but month must be set before day.
|
13
|
-
|
14
|
-
h2. Features
|
15
|
-
|
16
|
-
PartialDate::Date uses a 30 bit register as the backing store for date instances, and bit fiddling to get or set year, month and day values. As such it will perform well in a loop or collection of date objects.
|
17
|
-
|
18
|
-
Use @date.value@ to get or set an Integer value that can be used to rehydrate a date object, or save the date value to a persistance store in a readable Integer form e.g. 20121201 for 2012 December 01.
|
19
|
-
|
20
|
-
h2. Examples
|
21
|
-
|
22
|
-
bc.. require 'partial-date'
|
23
|
-
|
24
|
-
# Default initializer
|
25
|
-
date = PartialDate::Date.new
|
26
|
-
# =>
|
27
|
-
date.value
|
28
|
-
# => 0
|
29
|
-
|
30
|
-
# Initialize from a block of integers
|
31
|
-
date = PartialDate::Date.new {|d| d.year = 2012; d.month = 01}
|
32
|
-
# => 2012-01
|
33
|
-
date.value
|
34
|
-
# => 20120100
|
35
|
-
|
36
|
-
# Initialize from a block of strings
|
37
|
-
date = PartialDate::Date.new {|d| d.year = "2012"; d.month = "01"}
|
38
|
-
# => 2012-01
|
39
|
-
date.value
|
40
|
-
# => 20120100
|
41
|
-
|
42
|
-
# Initialize from the class load method - for rehydrating a date instance from a stored integer date value.
|
43
|
-
date = PartialDate::Date.load 20121201
|
44
|
-
# => 2012-12-01
|
45
|
-
date.year
|
46
|
-
# => 2012
|
47
|
-
date.month
|
48
|
-
# => 12
|
49
|
-
date.day
|
50
|
-
# => 1
|
51
|
-
|
52
|
-
h2. Install
|
53
|
-
|
54
|
-
@$ gem install partial-date@
|
55
|
-
|
56
|
-
h2. TODO
|
57
|
-
|
58
|
-
# @PartialDate::Date.parse@ method for construction from strings.
|
59
|
-
|
60
|
-
h2. Copyright
|
61
|
-
|
62
|
-
Copyright (c) 2012 Anthony Bouch
|
63
|
-
|
64
|
-
See {file:LICENSE.txt} for details.
|