carbon_date 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/README.md +2 -0
- data/carbon_date.gemspec +2 -0
- data/lib/carbon_date.rb +7 -0
- data/lib/carbon_date/date.rb +90 -64
- data/lib/carbon_date/formatter.rb +37 -19
- data/lib/carbon_date/standard_formatter.rb +68 -3
- data/lib/carbon_date/version.rb +1 -1
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c60c02d57fde03497403333831fb9c699374bd78
|
4
|
+
data.tar.gz: 1a65132b4dff055a69503b2c58138482872d11f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea46f3105ebf35dbf78b2dc9bfc66ec6e94e35a07fbe28f29db8b65a46e8e186efe02fc0a6d8855424b37dc279605181c2091c8c5ffbb984f4247f510fa55b3f
|
7
|
+
data.tar.gz: 02b78be58c703446b079467a916ab7d7f5d154805708e22cdde7ff17c66cd53e2dd853df87017f91db7499690614139278d6f193b2f331145dda9d13a0d719cd
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
[![Gem Version](http://img.shields.io/gem/v/carbon_date.svg?style=flat-square)](https://rubygems.org/gems/carbon_date)
|
2
|
+
[![Coverage Status](https://coveralls.io/repos/github/bradleymarques/carbon_date/badge.svg?branch=master)](https://coveralls.io/github/bradleymarques/carbon_date?branch=master)
|
3
|
+
[![Inline docs](http://inch-ci.org/github/bradleymarques/carbon_date.svg?branch=master)](http://inch-ci.org/github/bradleymarques/carbon_date)
|
2
4
|
[![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://bradleymarques.mit-license.org)
|
3
5
|
|
4
6
|
# CarbonDate
|
data/carbon_date.gemspec
CHANGED
@@ -36,6 +36,8 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency 'pry', '~> 0.10.3', '>= 0.10.3'
|
37
37
|
spec.add_development_dependency 'rdoc', '~> 4.2.2', '>= 4.2.2'
|
38
38
|
spec.add_development_dependency 'mocha', '~> 1.1.0', '>= 1.1.0'
|
39
|
+
spec.add_development_dependency 'coveralls', '~> 0.8.13', '>= 0.8.13'
|
40
|
+
|
39
41
|
|
40
42
|
spec.add_dependency 'activesupport', '~> 4.2.6', '>= 4.2.6'
|
41
43
|
end
|
data/lib/carbon_date.rb
CHANGED
@@ -3,6 +3,13 @@ require 'carbon_date/formatter'
|
|
3
3
|
require 'carbon_date/standard_formatter'
|
4
4
|
require 'carbon_date/version'
|
5
5
|
|
6
|
+
##
|
7
|
+
# Provides a custom implmentation of +Date+ with precision.
|
8
|
+
#
|
9
|
+
# Classes:
|
10
|
+
# - +Date+
|
11
|
+
# - +Formatter+
|
12
|
+
# - +StandardFormatter+ < +Formatter+
|
6
13
|
module CarbonDate
|
7
14
|
|
8
15
|
|
data/lib/carbon_date/date.rb
CHANGED
@@ -4,39 +4,68 @@ require 'carbon_date/standard_formatter'
|
|
4
4
|
module CarbonDate
|
5
5
|
|
6
6
|
##
|
7
|
-
#
|
7
|
+
# Models a date with a precision.
|
8
|
+
# The conventions of the Gregorian Calendar are used to model dates.
|
8
9
|
class Date
|
9
10
|
|
11
|
+
# The class-wide Formatter to use to turn CarbonDate::Dates into human-readable strings
|
10
12
|
@formatter = CarbonDate::StandardFormatter.new
|
11
13
|
|
12
14
|
class << self
|
15
|
+
# Used to get and set the CarbonDate::Date.formatter
|
13
16
|
attr_accessor :formatter
|
14
17
|
end
|
15
18
|
|
16
19
|
##
|
17
20
|
# The precisions available
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
{symbol: :billion_years, level: 0}
|
21
|
+
PRECISION =
|
22
|
+
[
|
23
|
+
:billion_years,
|
24
|
+
:hundred_million_years,
|
25
|
+
:ten_million_years,
|
26
|
+
:million_years,
|
27
|
+
:hundred_thousand_years,
|
28
|
+
:ten_thousand_years,
|
29
|
+
:millennium,
|
30
|
+
:century,
|
31
|
+
:decade,
|
32
|
+
:year,
|
33
|
+
:month,
|
34
|
+
:day,
|
35
|
+
:hour,
|
36
|
+
:minute,
|
37
|
+
:second
|
36
38
|
]
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
+
# The date's precision
|
41
|
+
attr_reader :precision
|
42
|
+
# The date's year. Cannot be 0 as there is no 0 year in the Gregorian Calendar.
|
43
|
+
attr_reader :year
|
44
|
+
# The date's month in range (1..12)
|
45
|
+
attr_reader :month
|
46
|
+
# The date's day counting from 1
|
47
|
+
attr_reader :day
|
48
|
+
# The date's hour in range (0..23)
|
49
|
+
attr_reader :hour
|
50
|
+
# The date's minute in range (0..59)
|
51
|
+
attr_reader :minute
|
52
|
+
# The date's second in range (0..59)
|
53
|
+
attr_reader :second
|
54
|
+
|
55
|
+
# Creates a new CarbonDate::Date
|
56
|
+
#
|
57
|
+
# Params:
|
58
|
+
# +year+ - The date's year, as an integer
|
59
|
+
# +month+ - The date's month, as an integer
|
60
|
+
# +day+ - The date's day, as an integer
|
61
|
+
# +hour+ - The date's hour, as an integer
|
62
|
+
# +minute+ - The date's minute, as an integer
|
63
|
+
# +second+ - The date's second, as an integer
|
64
|
+
# +:precision+ - The date's precision, as a symbol. For avaiable options, see CarbonDate::Date::PRECISION
|
65
|
+
# Raises:
|
66
|
+
# +ArgumentError+ if validations fail
|
67
|
+
# Returns:
|
68
|
+
# +CarbonDate::Date+ object
|
40
69
|
def initialize(year = 1970, month = 1, day = 1, hour = 0, minute = 0, second = 0, precision: :second)
|
41
70
|
month = 1 if month == 0
|
42
71
|
day = 1 if day == 0
|
@@ -47,97 +76,76 @@ module CarbonDate
|
|
47
76
|
self.second = second
|
48
77
|
end
|
49
78
|
|
50
|
-
##
|
51
79
|
# Sets the precision
|
52
|
-
#
|
53
|
-
# Raises ArgumentError if invalid symbol
|
80
|
+
# Raises +ArgumentError+ if invalid symbol
|
54
81
|
def precision=(value)
|
55
|
-
|
56
|
-
|
57
|
-
@precision = p
|
82
|
+
raise ArgumentError.new "Invalid precision #{value}" unless PRECISION.include? value
|
83
|
+
@precision = value
|
58
84
|
end
|
59
85
|
|
60
|
-
|
61
|
-
#
|
62
|
-
#
|
63
|
-
# Raises ArgumentError if invalid date
|
86
|
+
# An atomic function to set the date component (year, month and day)
|
87
|
+
# Raises +ArgumentError+ if invalid date
|
64
88
|
def set_date(year, month, day)
|
65
|
-
|
66
|
-
raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") unless (1..12).include? month
|
67
|
-
raise ArgumentError.new("Invalid date #{year}-#{month}-#{day}") if (year.nil? || year == 0)
|
68
|
-
|
89
|
+
raise invalid_date if (year.nil? || year == 0 || !((1..12).include? month))
|
69
90
|
begin
|
70
91
|
::Date.new(year, month, day)
|
71
92
|
rescue ArgumentError
|
72
|
-
raise
|
93
|
+
raise invalid_date
|
73
94
|
end
|
74
|
-
|
75
95
|
@year = year.to_i
|
76
96
|
@month = month
|
77
97
|
@day = day
|
78
|
-
|
79
98
|
end
|
80
99
|
|
81
|
-
##
|
82
100
|
# Sets the year. Calls set_date() to ensure atomicity.
|
83
101
|
def year=(value)
|
84
102
|
set_date(value, @month, @day)
|
85
103
|
end
|
86
104
|
|
87
|
-
##
|
88
105
|
# Sets the month. Calls set_date() to ensure atomicity.
|
89
|
-
#
|
90
|
-
# Raises ArgumentError if:
|
106
|
+
# Raises +ArgumentError+ if:
|
91
107
|
# - value is not in (1..12)
|
92
108
|
def month=(value)
|
93
109
|
set_date(@year, value, @day)
|
94
110
|
end
|
95
111
|
|
96
|
-
|
97
|
-
#
|
98
|
-
#
|
99
|
-
# Raises ArgumentError if:
|
112
|
+
# Sets the day. Calls set_date() to ensure atomicity.
|
113
|
+
# Raises +ArgumentError+ if:
|
100
114
|
# - value is not in (1..12)
|
101
115
|
def day=(value)
|
102
116
|
set_date(@year, @month, value)
|
103
117
|
end
|
104
118
|
|
105
|
-
##
|
106
119
|
# Sets the hour with validation
|
107
|
-
#
|
108
|
-
# Raises ArgumentError unless in the range (0..23)
|
120
|
+
# Raises +ArgumentError+ unless in the range (0..23)
|
109
121
|
def hour=(value)
|
110
122
|
raise ArgumentError.new "Invalid hour #{value}" unless (0..23).include? value
|
111
123
|
@hour = value
|
112
124
|
end
|
113
125
|
|
114
|
-
##
|
115
126
|
# Sets the minute with validation
|
116
|
-
#
|
117
|
-
# Raises ArgumentError unless in the range (0..59)
|
127
|
+
# Raises +ArgumentError+ unless in the range (0..59)
|
118
128
|
def minute=(value)
|
119
129
|
raise ArgumentError.new "Invalid minute #{value}" unless (0..59).include? value
|
120
130
|
@minute = value
|
121
131
|
end
|
122
132
|
|
123
|
-
##
|
124
133
|
# Sets the second with validation
|
125
|
-
#
|
126
|
-
# Raises ArgumentError unless in the range (0..59)
|
134
|
+
# Raises +ArgumentError+ unless in the range (0..59)
|
127
135
|
def second=(value)
|
128
136
|
raise ArgumentError.new "Invalid second #{value}" unless (0..59).include? value
|
129
137
|
@second = value
|
130
138
|
end
|
131
139
|
|
132
|
-
##
|
133
140
|
# Converts from an iso8601 datetime format, with precision
|
134
|
-
#
|
135
141
|
# Dates like these are found on Wikidata (https://www.wikidata.org)
|
136
|
-
#
|
142
|
+
# Params:
|
137
143
|
# +string+ -> the iso8601 datetime in the form +1989-03-23T23:11:08Z
|
138
144
|
# +precision_level+ -> an integer between 0 and 14 (see CarbonDate::Date::PRECISION)
|
145
|
+
# Returns:
|
146
|
+
# +CarbonDate::Date+ object
|
139
147
|
def self.iso8601(string, precision_level)
|
140
|
-
p = PRECISION
|
148
|
+
p = PRECISION[precision_level]
|
141
149
|
raise ArgumentError.new("Invalid precision level #{precision_level}") unless p
|
142
150
|
# If there is an initial '-' symbol on the year, it needs to be treateded differenty than the other '-'.
|
143
151
|
# Example: -0500-01-01 is the 1st January 500 BCE
|
@@ -149,39 +157,57 @@ module CarbonDate
|
|
149
157
|
end
|
150
158
|
d = string.split('T').map { |x| x.split(/[-:]/) }.flatten.map(&:to_i)
|
151
159
|
year = bce ? -d[0] : d[0]
|
152
|
-
CarbonDate::Date.new(year, d[1], d[2], d[3], d[4], d[5], precision: p
|
160
|
+
CarbonDate::Date.new(year, d[1], d[2], d[3], d[4], d[5], precision: p)
|
153
161
|
end
|
154
162
|
|
155
|
-
|
156
|
-
# Prints a human-readable version of the date, using a Formatter
|
163
|
+
# Prints a human-readable version of the date, using CarbonDate::Date.formatter
|
157
164
|
def to_s
|
158
165
|
CarbonDate::Date.formatter.date_to_string(self)
|
159
166
|
end
|
160
167
|
|
161
|
-
##
|
162
168
|
# Convert to a standard Ruby Date object
|
169
|
+
# Returns:
|
170
|
+
# +::Date+ object
|
163
171
|
def to_date
|
164
172
|
::Date.new(@year, @month, @day)
|
165
173
|
end
|
166
174
|
|
167
|
-
##
|
168
175
|
# Convert into a standard Ruby DateTime object
|
176
|
+
# Returns:
|
177
|
+
# +::DateTime+ object
|
169
178
|
def to_datetime
|
170
179
|
::DateTime.new(@year, @month, @day, @hour, @minute, @second)
|
171
180
|
end
|
172
181
|
|
182
|
+
# Test equality of two CarbonDate::Dates
|
183
|
+
# For equality, the two dates have to have the same:
|
184
|
+
# - precision
|
185
|
+
# - year
|
186
|
+
# - month
|
187
|
+
# - day
|
188
|
+
# - hour
|
189
|
+
# - minute
|
190
|
+
# - second
|
173
191
|
def ==(another_date)
|
174
192
|
return false if self.precision != another_date.precision
|
175
193
|
self.to_datetime == another_date.to_datetime
|
176
194
|
end
|
177
195
|
|
196
|
+
# Tests if this CarbonDate::Date is in the past relative to the other CarbonDate::Date
|
197
|
+
# Defers to DateTime#<=
|
178
198
|
def <=(another_date)
|
179
199
|
self.to_datetime <= another_date.to_datetime
|
180
200
|
end
|
181
201
|
|
202
|
+
# Tests if this CarbonDate::Date is in the future relative to the other CarbonDate::Date
|
203
|
+
# Defers to DateTime#>=
|
182
204
|
def >=(another_date)
|
183
205
|
self.to_datetime >= another_date.to_datetime
|
184
206
|
end
|
185
207
|
|
208
|
+
def invalid_date
|
209
|
+
ArgumentError.new("Invalid date #{year}-#{month}-#{day}")
|
210
|
+
end
|
211
|
+
|
186
212
|
end
|
187
213
|
end
|
@@ -1,28 +1,46 @@
|
|
1
1
|
module CarbonDate
|
2
2
|
|
3
3
|
##
|
4
|
-
# Responsible for formatting a CarbonDate::Date
|
4
|
+
# Responsible for formatting a CarbonDate::Date as a human-readable string. Used when CarbonDate::Date#to_s is called.
|
5
|
+
#
|
6
|
+
# You can extend Formatter to create your own custom output for dates.
|
7
|
+
# class MyCustomFormatter < CarbonDate::Formatter
|
8
|
+
# def year(date)
|
9
|
+
# # ...
|
10
|
+
# end
|
11
|
+
# # ...
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# Then, to use your custom formatter, simply do:
|
15
|
+
# CarbonDate::Date.formatter = MyCustomFormatter.new
|
16
|
+
# All subsequent dates will be formatted using your custom formatter.
|
17
|
+
# Implementations of Formatter need to override all of the following methods:
|
18
|
+
# - +billion_years(date)+
|
19
|
+
# - +hundred_million_years(date)+
|
20
|
+
# - +ten_million_years(date)+
|
21
|
+
# - +million_years(date)+
|
22
|
+
# - +hundred_thousand_years(date)+
|
23
|
+
# - +ten_thousand_years(date)+
|
24
|
+
# - +millennium(date)+
|
25
|
+
# - +century(date)+
|
26
|
+
# - +decade(date)+
|
27
|
+
# - +year(date)+
|
28
|
+
# - +month(date)+
|
29
|
+
# - +day(date)+
|
30
|
+
# - +hour(date)+
|
31
|
+
# - +minute(date)+
|
32
|
+
# - +second(date)+
|
33
|
+
# All of the above methods take a CarbonDate::Date as a parameter.
|
5
34
|
class Formatter
|
6
35
|
|
36
|
+
##
|
37
|
+
# Formats a CarbonDate::Date object as a human-readable string
|
7
38
|
def date_to_string(date)
|
8
|
-
precision = date.precision
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
when :million_years then million_years(date)
|
14
|
-
when :hundred_thousand_years then hundred_thousand_years(date)
|
15
|
-
when :ten_thousand_years then ten_thousand_years(date)
|
16
|
-
when :millennium then millennium(date)
|
17
|
-
when :century then century(date)
|
18
|
-
when :decade then decade(date)
|
19
|
-
when :year then year(date)
|
20
|
-
when :month then month(date)
|
21
|
-
when :day then day(date)
|
22
|
-
when :hour then hour(date)
|
23
|
-
when :minute then minute(date)
|
24
|
-
when :second then second(date)
|
25
|
-
else raise StandardError.new("Unrecognized precision: #{precision}")
|
39
|
+
precision = date.precision
|
40
|
+
if CarbonDate::Date::PRECISION.include? precision # Call me paranoid: whitelist the available functions
|
41
|
+
public_send(precision, date)
|
42
|
+
else
|
43
|
+
raise StandardError.new("Unrecognized precision: #{precision}")
|
26
44
|
end
|
27
45
|
end
|
28
46
|
end
|
@@ -6,86 +6,135 @@ module CarbonDate
|
|
6
6
|
# The default formatter for CarbonDate::Date
|
7
7
|
class StandardFormatter < Formatter
|
8
8
|
|
9
|
-
##
|
10
9
|
# Suffix to use for Before Common Era dates (quite often BCE or BC)
|
11
10
|
BCE_SUFFIX = 'BCE'
|
12
11
|
|
12
|
+
# Collection of strings denoting month names for this Formatter
|
13
13
|
MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
# Formats a CarbonDate::Date with year precision as a string
|
16
|
+
# Returns:
|
17
|
+
# A human-readable string representing the Date
|
17
18
|
def year(date)
|
18
19
|
y = date.year.abs.to_s
|
19
20
|
return [y, BCE_SUFFIX].join(' ') if (date.year <= -1)
|
20
21
|
y
|
21
22
|
end
|
22
23
|
|
24
|
+
# Formats a CarbonDate::Date with month precision as a string
|
25
|
+
# Returns:
|
26
|
+
# A human-readable string representing the Date
|
23
27
|
def month(date)
|
24
28
|
[MONTHS[date.month - 1], year(date)].join(', ')
|
25
29
|
end
|
26
30
|
|
31
|
+
# Formats a CarbonDate::Date with day precision as a string
|
32
|
+
# Returns:
|
33
|
+
# A human-readable string representing the Date
|
27
34
|
def day(date)
|
28
35
|
[date.day.ordinalize.to_s, month(date)].join(' ')
|
29
36
|
end
|
30
37
|
|
38
|
+
# Formats a CarbonDate::Date with hour precision as a string
|
39
|
+
# Returns:
|
40
|
+
# A human-readable string representing the Date
|
31
41
|
def hour(date)
|
32
42
|
h = date.minute >= 30 ? date.hour + 1 : date.hour
|
33
43
|
time = [pad(h.to_s), '00'].join(':')
|
34
44
|
[time, day(date)].join(' ')
|
35
45
|
end
|
36
46
|
|
47
|
+
# Formats a CarbonDate::Date with minute precision as a string
|
48
|
+
# Returns:
|
49
|
+
# A human-readable string representing the Date
|
37
50
|
def minute(date)
|
38
51
|
time = [pad(date.hour.to_s), pad(date.minute.to_s)].join(':')
|
39
52
|
[time, day(date)].join(' ')
|
40
53
|
end
|
41
54
|
|
55
|
+
# Formats a CarbonDate::Date with second precision as a string
|
56
|
+
# Returns:
|
57
|
+
# A human-readable string representing the Date
|
42
58
|
def second(date)
|
43
59
|
time = [pad(date.hour.to_s), pad(date.minute.to_s), pad(date.second.to_s)].join(':')
|
44
60
|
[time, day(date)].join(' ')
|
45
61
|
end
|
46
62
|
|
63
|
+
# Formats a CarbonDate::Date with decade precision
|
64
|
+
# Returns:
|
65
|
+
# A human-readable string representing the Date
|
47
66
|
def decade(date)
|
48
67
|
d = ((date.year.abs.to_i / 10) * 10).to_s + 's'
|
49
68
|
return [d, BCE_SUFFIX].join(' ') if (date.year <= -1)
|
50
69
|
d
|
51
70
|
end
|
52
71
|
|
72
|
+
# Formats a CarbonDate::Date with century precision
|
73
|
+
# Returns:
|
74
|
+
# A human-readable string representing the Date
|
53
75
|
def century(date)
|
54
76
|
c = ((date.year.abs.to_i / 100) + 1).ordinalize + ' century'
|
55
77
|
return [c, BCE_SUFFIX].join(' ') if (date.year <= -1)
|
56
78
|
c
|
57
79
|
end
|
58
80
|
|
81
|
+
# Formats a CarbonDate::Date with millennium precision
|
82
|
+
# Returns:
|
83
|
+
# A human-readable string representing the Date
|
59
84
|
def millennium(date)
|
60
85
|
m = ((date.year.abs.to_i / 1000) + 1).ordinalize + ' millennium'
|
61
86
|
return [m, BCE_SUFFIX].join(' ') if (date.year <= -1)
|
62
87
|
m
|
63
88
|
end
|
64
89
|
|
90
|
+
# Formats a CarbonDate::Date with ten_thousand_years precision
|
91
|
+
# Returns:
|
92
|
+
# A human-readable string representing the Date
|
65
93
|
def ten_thousand_years(date)
|
66
94
|
coarse_precision(date.year, 10e3.to_i)
|
67
95
|
end
|
68
96
|
|
97
|
+
# Formats a CarbonDate::Date with hundred_thousand_years precision
|
98
|
+
# Returns:
|
99
|
+
# A human-readable string representing the Date
|
69
100
|
def hundred_thousand_years(date)
|
70
101
|
coarse_precision(date.year, 100e3.to_i)
|
71
102
|
end
|
72
103
|
|
104
|
+
# Formats a CarbonDate::Date with million_years precision
|
105
|
+
# Returns:
|
106
|
+
# A human-readable string representing the Date
|
73
107
|
def million_years(date)
|
74
108
|
coarse_precision(date.year, 1e6.to_i)
|
75
109
|
end
|
76
110
|
|
111
|
+
# Formats a CarbonDate::Date with ten_million_years precision
|
112
|
+
# Returns:
|
113
|
+
# A human-readable string representing the Date
|
77
114
|
def ten_million_years(date)
|
78
115
|
coarse_precision(date.year, 10e6.to_i)
|
79
116
|
end
|
80
117
|
|
118
|
+
# Formats a CarbonDate::Date with hundred_million_years precision
|
119
|
+
# Returns:
|
120
|
+
# A human-readable string representing the Date
|
81
121
|
def hundred_million_years(date)
|
82
122
|
coarse_precision(date.year, 100e6.to_i)
|
83
123
|
end
|
84
124
|
|
125
|
+
# Formats a CarbonDate::Date with billion_years precision
|
126
|
+
# Returns:
|
127
|
+
# A human-readable string representing the Date
|
85
128
|
def billion_years(date)
|
86
129
|
coarse_precision(date.year, 1e9.to_i)
|
87
130
|
end
|
88
131
|
|
132
|
+
# A helper function used to format dates that have less than millenium precision
|
133
|
+
# Params:
|
134
|
+
# +date_year+ The year component of the CarbonDate::Date being formatted
|
135
|
+
# +interval+ The precision in years
|
136
|
+
# Returns:
|
137
|
+
# A human-readable string representing the Date
|
89
138
|
def coarse_precision(date_year, interval)
|
90
139
|
|
91
140
|
date_year = date_year.to_i
|
@@ -102,10 +151,26 @@ module CarbonDate
|
|
102
151
|
nil
|
103
152
|
end
|
104
153
|
|
154
|
+
# Converts an integer number into a human-readable string with thousands delimiters.
|
155
|
+
# Example:
|
156
|
+
# number_with_delimiter(1234567890, ',')
|
157
|
+
# => 1,234,567,890
|
158
|
+
# Params:
|
159
|
+
# +n+ the number to be delimited. Will be converted to an integer
|
160
|
+
# +delim+ the string to be used as the thousands delimiter. Defaults to ','
|
105
161
|
def number_with_delimiter(n, delim = ',')
|
106
162
|
n.to_i.to_s.reverse.chars.each_slice(3).map(&:join).join(delim).reverse
|
107
163
|
end
|
108
164
|
|
165
|
+
# Pad a string with '0' to ensure it has two characters.
|
166
|
+
# If a string of 2 or more characters is used as parameter, will not alter the string.
|
167
|
+
# Example:
|
168
|
+
# pad('1')
|
169
|
+
# => "01"
|
170
|
+
# Params:
|
171
|
+
# +s+ The string to pad.
|
172
|
+
# Returns:
|
173
|
+
# A string of at least 2 characters
|
109
174
|
def pad(s)
|
110
175
|
s.rjust(2, '0')
|
111
176
|
end
|
data/lib/carbon_date/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carbon_date
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bradley Marques
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -184,6 +184,26 @@ dependencies:
|
|
184
184
|
- - ">="
|
185
185
|
- !ruby/object:Gem::Version
|
186
186
|
version: 1.1.0
|
187
|
+
- !ruby/object:Gem::Dependency
|
188
|
+
name: coveralls
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: 0.8.13
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: 0.8.13
|
197
|
+
type: :development
|
198
|
+
prerelease: false
|
199
|
+
version_requirements: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - "~>"
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: 0.8.13
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: 0.8.13
|
187
207
|
- !ruby/object:Gem::Dependency
|
188
208
|
name: activesupport
|
189
209
|
requirement: !ruby/object:Gem::Requirement
|