partial-date 1.1.7 → 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|