natural_time 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +26 -24
- data/lib/natural_time/version.rb +2 -2
- data/lib/natural_time.rb +187 -51
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4b40e761d45e9aa1632c1e6569005bf60c1ce6ba4fea1f897740238f70ddf6d
|
4
|
+
data.tar.gz: 42b36e25bcb2392cf293dcb2bdd7d3f77cfcd2cdc8aad56e2718e7187baed5c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c432a254a76167015c30cf860152e56dc22c077c00b0306749622aabc0001f6721988fa36e51054654b2af7dffc418f4402f6be02cea8d47d954ceaef08c775
|
7
|
+
data.tar.gz: 4ce289e049c3bb9aaf96f19bfc8fc1eaf28ef0ad3417cf7bea9fc813710013370c464f1ec55abae1515ded8faca212e5993756160625f527a12715d10ed776e7
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -6,59 +6,61 @@ NaturalTime outputs a duration in natural language.
|
|
6
6
|
|
7
7
|
### Sentence
|
8
8
|
|
9
|
-
The
|
9
|
+
The `to_sentence` method will output the duration in time in natural language
|
10
10
|
and formatted like a sentence.
|
11
11
|
|
12
|
-
NaturalTime.
|
12
|
+
NaturalTime.to_sentence(65) #=> "1 minute and 5 seconds"
|
13
13
|
|
14
|
-
NaturalTime.
|
14
|
+
NaturalTime.to_sentence(120) #=> "2 minutes"
|
15
15
|
|
16
|
-
NaturalTime.
|
16
|
+
NaturalTime.to_sentence(10000) #=> "2 hours, 46 minutes, and 40 seconds"
|
17
17
|
|
18
18
|
### String
|
19
19
|
|
20
|
-
The
|
20
|
+
The `to_s` command will separate the units with commas but with no "and":
|
21
21
|
|
22
|
-
NaturalTime.
|
22
|
+
NaturalTime.to_s(65) #=> "1 minute, 5 seconds"
|
23
23
|
|
24
|
-
NaturalTime.
|
24
|
+
NaturalTime.to_s(10000) #=> "2 hours, 46 minutes, 40 seconds"
|
25
25
|
|
26
26
|
### Array
|
27
27
|
|
28
|
-
NaturalTime instances can also be output to an array with
|
28
|
+
NaturalTime instances can also be output to an array with `to_array`:
|
29
29
|
|
30
|
-
NaturalTime.
|
30
|
+
NaturalTime.to_array(65) #=> ["1 minutes", "5 seconds"]
|
31
31
|
|
32
|
-
NaturalTime.
|
32
|
+
NaturalTime.to_array(120) #=> ["2 minutes"]
|
33
33
|
|
34
34
|
### Precision
|
35
35
|
|
36
|
-
NaturalTime can return the amount of time to a specific precision.
|
36
|
+
NaturalTime can return the amount of time to a specific precision. If all you
|
37
|
+
want is the greatest unit:
|
37
38
|
|
38
|
-
NaturalTime.
|
39
|
+
NaturalTime.to_sentence(65, precision: 1) #=> "1 minute"
|
39
40
|
|
40
|
-
NaturalTime.
|
41
|
+
NaturalTime.to_sentence(10000, precision: 1) #=> "2 hours"
|
41
42
|
|
42
|
-
NaturalTime.
|
43
|
+
NaturalTime.to_sentence(10000, precision: 2) #=> "2 hours and 46 minutes"
|
43
44
|
|
44
45
|
### Distance
|
45
46
|
|
46
|
-
If you want to use NaturalTime to show an elapsed time and you don't care if
|
47
|
-
past or the future, use the
|
48
|
-
|
47
|
+
If you want to use NaturalTime to show an elapsed time and you don't care if
|
48
|
+
it's in the past or the future, use the `natural_time` or `to_sentence`
|
49
|
+
methods, or the `to_a` method if you need the units in an array.
|
49
50
|
|
50
|
-
If you're measuring distances that may be in the past or the future, the
|
51
|
-
method will return a sentence indicating how long ago or in
|
51
|
+
If you're measuring distances that may be in the past or the future, the
|
52
|
+
`distance` method will return a sentence indicating how long ago or in
|
53
|
+
the future is your duration.
|
52
54
|
|
53
|
-
NaturalTime.
|
55
|
+
NaturalTime.distance(65) #=> "1 minute and 5 seconds from now"
|
54
56
|
|
55
|
-
NaturalTime.
|
57
|
+
NaturalTime.distance(-65) #=> "1 minute and 5 seconds ago"
|
56
58
|
|
57
|
-
It works with
|
59
|
+
It works with `:precision` too:
|
58
60
|
|
59
|
-
NaturalTime.
|
61
|
+
NaturalTime.distance(10000, precision: 1) #=> "2 hours from now"
|
60
62
|
|
61
|
-
NaturalTime.
|
63
|
+
NaturalTime.distance(-10000, precision: 2) #=> "2 hours and 46 minutes ago"
|
62
64
|
|
63
65
|
|
64
66
|
## Note on Patches/Pull Requests
|
data/lib/natural_time/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.
|
1
|
+
module NaturalTime
|
2
|
+
VERSION = "0.4.0"
|
3
3
|
end
|
data/lib/natural_time.rb
CHANGED
@@ -1,70 +1,206 @@
|
|
1
1
|
require "natural_time/version"
|
2
2
|
require 'active_support/core_ext/integer/time'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
# # NaturalTime
|
5
|
+
#
|
6
|
+
# NaturalTime outputs a duration in natural language.
|
7
|
+
#
|
8
|
+
# ## Usage
|
9
|
+
#
|
10
|
+
# ### Sentence
|
11
|
+
#
|
12
|
+
# The `to_sentence` method will output the duration in time in natural language
|
13
|
+
# and formatted like a sentence.
|
14
|
+
#
|
15
|
+
# NaturalTime.to_sentence(65) #=> "1 minute and 5 seconds"
|
16
|
+
#
|
17
|
+
# NaturalTime.to_sentence(120) #=> "2 minutes"
|
18
|
+
#
|
19
|
+
# NaturalTime.to_sentence(10000) #=> "2 hours, 46 minutes, and 40 seconds"
|
20
|
+
#
|
21
|
+
# ### String
|
22
|
+
#
|
23
|
+
# The `to_s` command will separate the units with commas but with no "and":
|
24
|
+
#
|
25
|
+
# NaturalTime.to_s(65) #=> "1 minute, 5 seconds"
|
26
|
+
#
|
27
|
+
# NaturalTime.to_s(10000) #=> "2 hours, 46 minutes, 40 seconds"
|
28
|
+
#
|
29
|
+
# ### Array
|
30
|
+
#
|
31
|
+
# NaturalTime instances can also be output to an array with `to_array`:
|
32
|
+
#
|
33
|
+
# NaturalTime.to_array(65) #=> ["1 minutes", "5 seconds"]
|
34
|
+
#
|
35
|
+
# NaturalTime.to_array(120) #=> ["2 minutes"]
|
36
|
+
#
|
37
|
+
# ### Precision
|
38
|
+
#
|
39
|
+
# NaturalTime can return the amount of time to a specific precision. If all
|
40
|
+
# you want is the greatest unit:
|
41
|
+
#
|
42
|
+
# NaturalTime.to_sentence(65, precision: 1) #=> "1 minute"
|
43
|
+
#
|
44
|
+
# NaturalTime.to_sentence(10000, precision: 1) #=> "2 hours"
|
45
|
+
#
|
46
|
+
# NaturalTime.to_sentence(10000, precision: 2) #=> "2 hours and 46 minutes"
|
47
|
+
#
|
48
|
+
# ### Distance
|
49
|
+
#
|
50
|
+
# If you want to use NaturalTime to show an elapsed time and you don't care if it's in the
|
51
|
+
# past or the future, use the `natural_time` or `to_sentence` methods, or the
|
52
|
+
# `to_array` method if you need the units in an array.
|
53
|
+
#
|
54
|
+
# If you're measuring distances that may be in the past or the future, the `distance`
|
55
|
+
# method will return a sentence indicating how long ago or in the future is your duration.
|
56
|
+
#
|
57
|
+
# NaturalTime.distance(65) #=> "1 minute and 5 seconds from now"
|
58
|
+
#
|
59
|
+
# NaturalTime.distance(-65) #=> "1 minute and 5 seconds ago"
|
60
|
+
#
|
61
|
+
# It works with `:precision` too:
|
62
|
+
#
|
63
|
+
# NaturalTime.distance(10000, precision: 1) #=> "2 hours from now"
|
64
|
+
#
|
65
|
+
# NaturalTime.distance(-10000, precision: 2) #=> "2 hours and 46 minutes ago"
|
66
|
+
#
|
67
|
+
module NaturalTime
|
68
|
+
class << self
|
69
|
+
# Return a natural-language representation of a duration in time.
|
70
|
+
#
|
71
|
+
# @param [Integer] duration a duration in time
|
72
|
+
# @param [Integer] precision level of precision for the
|
73
|
+
# natural-language representation
|
74
|
+
#
|
75
|
+
# @return [String]
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# NaturalTime.to_sentence(65) #=> "1 minute and 5 seconds"
|
79
|
+
#
|
80
|
+
# NaturalTime.to_sentence(120) #=> "2 minutes"
|
81
|
+
#
|
82
|
+
# NaturalTime.to_sentence(10000) #=> "2 hours, 46 minutes, and 40 seconds"
|
83
|
+
#
|
84
|
+
def natural_time(duration, precision: nil)
|
85
|
+
to_array(duration, precision: precision).join(", ")
|
86
|
+
end
|
8
87
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
@
|
13
|
-
@
|
14
|
-
|
15
|
-
|
88
|
+
# Return a natural-language representation of a distance in time, relative
|
89
|
+
# to now.
|
90
|
+
#
|
91
|
+
# @param [Integer] duration a duration in time
|
92
|
+
# @param [Integer] precision level of precision for the
|
93
|
+
# natural-language representation
|
94
|
+
#
|
95
|
+
# @return [String]
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
# If you're measuring distances that may be in the past or the future, the `distance`
|
99
|
+
# method will return a sentence indicating how long ago or in the future is your duration.
|
100
|
+
#
|
101
|
+
# NaturalTime.distance(65) #=> "1 minute and 5 seconds from now"
|
102
|
+
#
|
103
|
+
# NaturalTime.distance(-65) #=> "1 minute and 5 seconds ago"
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# It works with `:precision` too:
|
107
|
+
#
|
108
|
+
# NaturalTime.distance(10000, precision: 1) #=> "2 hours from now"
|
109
|
+
#
|
110
|
+
# NaturalTime.distance(-10000, precision: 2) #=> "2 hours and 46 minutes ago"
|
111
|
+
#
|
112
|
+
def distance(duration, precision: nil)
|
113
|
+
if duration < 1
|
114
|
+
modifier = "ago"
|
115
|
+
else
|
116
|
+
modifier = "from now"
|
117
|
+
end
|
118
|
+
"#{to_sentence(duration, precision: precision)} #{modifier}"
|
119
|
+
end
|
16
120
|
|
17
|
-
|
18
|
-
|
19
|
-
|
121
|
+
# Return a natural-language representation of a duration in time, separating the
|
122
|
+
# units with commas but with no "and".
|
123
|
+
#
|
124
|
+
# @param [Integer] duration a duration in time
|
125
|
+
# @param [Integer] precision level of precision for the
|
126
|
+
# natural-language representation
|
127
|
+
#
|
128
|
+
# @return [String]
|
129
|
+
#
|
130
|
+
# @example
|
131
|
+
# NaturalTime.to_s(65) #=> "1 minute, 5 seconds"
|
132
|
+
#
|
133
|
+
# NaturalTime.to_s(10000) #=> "2 hours, 46 minutes, 40 seconds"
|
134
|
+
#
|
135
|
+
def to_string(duration, precision: nil)
|
136
|
+
natural_time(duration, precision: precision)
|
137
|
+
end
|
20
138
|
|
21
|
-
|
22
|
-
|
23
|
-
|
139
|
+
# Return the duration in time in natural-language and formatted like a sentence.
|
140
|
+
#
|
141
|
+
# @param [Integer] duration a duration in time
|
142
|
+
# @param [Integer] precision level of precision for the
|
143
|
+
# natural-language representation
|
144
|
+
#
|
145
|
+
# @return [String]
|
146
|
+
#
|
147
|
+
# @example
|
148
|
+
# NaturalTime.to_sentence(65) #=> "1 minute and 5 seconds"
|
149
|
+
#
|
150
|
+
# NaturalTime.to_sentence(120) #=> "2 minutes"
|
151
|
+
#
|
152
|
+
# NaturalTime.to_sentence(10000) #=> "2 hours, 46 minutes, and 40 seconds"
|
153
|
+
#
|
154
|
+
def to_sentence(duration, precision: nil)
|
155
|
+
to_array(duration, precision: precision).to_sentence
|
156
|
+
end
|
24
157
|
|
25
|
-
|
26
|
-
|
27
|
-
|
158
|
+
# Return the natural-language elements of a duration in an array.
|
159
|
+
#
|
160
|
+
# @param [Integer] duration a duration in time
|
161
|
+
# @param [Integer] precision level of precision for the
|
162
|
+
# natural-language representation
|
163
|
+
#
|
164
|
+
# @return [Array<String>]
|
165
|
+
#
|
166
|
+
# @example
|
167
|
+
# NaturalTime.to_array(65) #=> ["1 minutes", "5 seconds"]
|
168
|
+
#
|
169
|
+
# NaturalTime.to_array(120) #=> ["2 minutes"]
|
170
|
+
#
|
171
|
+
def to_array(duration, precision: nil)
|
172
|
+
[elapsed_time(duration, precision: precision)].flatten
|
173
|
+
end
|
28
174
|
|
29
|
-
|
30
|
-
[elapsed_time(duration)].flatten
|
31
|
-
end
|
175
|
+
private
|
32
176
|
|
33
|
-
|
34
|
-
to_a
|
35
|
-
end
|
177
|
+
UNITS_OF_TIME = [["year", "years"], ["month", "months"], ["week", "weeks"], ["day", "days"], ["hour", "hours"], ["minute", "minutes"]]
|
36
178
|
|
37
|
-
|
38
|
-
|
39
|
-
modifier = "ago"
|
40
|
-
else
|
41
|
-
modifier = "from now"
|
42
|
-
end
|
43
|
-
"#{to_sentence} #{modifier}"
|
44
|
-
end
|
179
|
+
def elapsed_time(duration, precision: nil)
|
180
|
+
duration = duration.to_i.abs
|
45
181
|
|
46
|
-
|
47
|
-
return "0 seconds" if duration_in_seconds <= 0
|
182
|
+
return "0 seconds" if duration <= 0
|
48
183
|
|
49
|
-
|
184
|
+
elapsed_time = []
|
50
185
|
|
51
|
-
|
186
|
+
seconds_left = duration
|
52
187
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
188
|
+
UNITS_OF_TIME.each do |period|
|
189
|
+
amount = (seconds_left / 1.send(period.first)).to_i
|
190
|
+
str = amount == 1 ? period[0] : period[1]
|
191
|
+
elapsed_time << "#{amount} #{str}" if amount > 0
|
192
|
+
seconds_left = seconds_left % 1.send(period.first)
|
193
|
+
end
|
59
194
|
|
60
|
-
|
61
|
-
|
62
|
-
|
195
|
+
seconds = seconds_left % 1.minute
|
196
|
+
str = seconds == 1 ? "second" : "seconds"
|
197
|
+
elapsed_time << "#{seconds.to_i} #{str}" unless (seconds == 0 && elapsed_time.compact.length > 0)
|
63
198
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
199
|
+
if precision
|
200
|
+
elapsed_time.compact.first(precision)
|
201
|
+
else
|
202
|
+
elapsed_time.compact
|
203
|
+
end
|
68
204
|
end
|
69
205
|
end
|
70
206
|
end
|