hpoydar-chronic_duration 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -2
- data/lib/chronic_duration.rb +49 -0
- data/spec/chronic_duration_spec.rb +25 -0
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
= Chronic Duration
|
2
2
|
|
3
|
-
A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.)
|
3
|
+
A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.)
|
4
|
+
|
5
|
+
The reverse can also be accomplished with the output method. So pass in seconds and you will get values like 4 ins 31.51 secs.
|
4
6
|
|
5
7
|
== Installation
|
6
8
|
|
@@ -13,6 +15,8 @@ A simple Ruby natural language parser for elapsed time. (For example, 4 hours an
|
|
13
15
|
=> true
|
14
16
|
>> ChronicDuration.parse('4 minutes and 30 seconds')
|
15
17
|
=> 270
|
18
|
+
>> ChronicDuration.output(270)
|
19
|
+
=> 4 mins 30 secs
|
16
20
|
|
17
21
|
Nil is returned if the string can't be parsed
|
18
22
|
|
@@ -33,4 +37,5 @@ Examples of parse-able strings:
|
|
33
37
|
|
34
38
|
* Benchmark and optimize
|
35
39
|
* Context specific matching (E.g., for '4m30s', assume 'm' is minutes)
|
36
|
-
* Smartly parse vacation-like durations (E.g., '4 days and 3 nights')
|
40
|
+
* Smartly parse vacation-like durations (E.g., '4 days and 3 nights')
|
41
|
+
* Allow alternative formatting for output
|
data/lib/chronic_duration.rb
CHANGED
@@ -6,8 +6,57 @@ module ChronicDuration
|
|
6
6
|
result == 0 ? nil : result
|
7
7
|
end
|
8
8
|
|
9
|
+
# Refactor, DRY up, make recursive
|
10
|
+
def output(seconds)
|
11
|
+
|
12
|
+
years = months = days = hours = minutes = 0
|
13
|
+
|
14
|
+
if seconds >= 60
|
15
|
+
minutes = (seconds / 60).to_i
|
16
|
+
seconds = seconds % 60
|
17
|
+
if minutes >= 60
|
18
|
+
hours = (minutes / 60).to_i
|
19
|
+
minutes = (minutes % 60).to_i
|
20
|
+
if hours >= 24
|
21
|
+
days = (hours / 24).to_i
|
22
|
+
hours = (hours % 24).to_i
|
23
|
+
if days >= 30
|
24
|
+
months = (days / 30).to_i
|
25
|
+
days = (days % 30).to_i
|
26
|
+
if months >= 12
|
27
|
+
years = (months / 12).to_i
|
28
|
+
months = (months % 12).to_i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
result = []
|
36
|
+
|
37
|
+
result << pluralize(years, 'yr')
|
38
|
+
result << pluralize(months, 'mo')
|
39
|
+
result << pluralize(days, 'day')
|
40
|
+
result << pluralize(hours, 'hr')
|
41
|
+
result << pluralize(minutes, 'min')
|
42
|
+
result << pluralize(seconds, 'sec')
|
43
|
+
|
44
|
+
result = result.join(' ').squeeze(' ').strip
|
45
|
+
return nil if result.length == 0
|
46
|
+
|
47
|
+
result
|
48
|
+
end
|
49
|
+
|
9
50
|
private
|
10
51
|
|
52
|
+
# A poor man's pluralizer
|
53
|
+
def pluralize(number, word)
|
54
|
+
return '' if number == 0
|
55
|
+
res = "#{number} #{word}"
|
56
|
+
res << 's' unless number == 1
|
57
|
+
res
|
58
|
+
end
|
59
|
+
|
11
60
|
def calculate_from_words(string)
|
12
61
|
val = 0
|
13
62
|
words = string.split(' ')
|
@@ -46,6 +46,31 @@ describe ChronicDuration, '.parse' do
|
|
46
46
|
|
47
47
|
end
|
48
48
|
|
49
|
+
describe ChronicDuration, '.output' do
|
50
|
+
|
51
|
+
@exemplars = {
|
52
|
+
'1 min 20 secs' => 60 + 20,
|
53
|
+
'1 min 20.51 secs' => 60 + 20.51,
|
54
|
+
'3 mins 20.51 secs' => 3 * 60 + 20.51,
|
55
|
+
'4 hrs 1 min 1 sec' => 4 * 3600 + 60 + 1,
|
56
|
+
'3 mins 4 secs' => 3 * 60 + 4,
|
57
|
+
'2 hrs 20 mins' => 2 * 3600 + 20 * 60,
|
58
|
+
'1 mo 1 day' => 1 * 30 * 24 * 3600 + 24 * 3600,
|
59
|
+
'6 mos 1 day' => 6 * 30 * 24 * 3600 + 24 * 3600,
|
60
|
+
'6 mos 2 days' => 6 * 30 * 24 * 3600 + 2 * 24 * 3600,
|
61
|
+
'2 hrs 30 mins' => 2.5 * 3600
|
62
|
+
}
|
63
|
+
|
64
|
+
|
65
|
+
@exemplars.each do |k, v|
|
66
|
+
it "should properly output a duration of #{v}" do
|
67
|
+
ChronicDuration.output(v).should == k
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
49
74
|
# Some of the private methods deserve some spec'ing to aid
|
50
75
|
# us in development...
|
51
76
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hpoydar-chronic_duration
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henry Poydar
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-01-
|
12
|
+
date: 2009-01-14 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.)
|
16
|
+
description: A simple Ruby natural language parser for elapsed time. (For example, 4 hours and 30 minutes, 6 minutes 4 seconds, 3 days, etc.) Returns all results in seconds. Will return an integer unless you get tricky and need a float. (4 minutes and 13.47 seconds, for example.) The reverse can also be performed via the output method.
|
17
17
|
email: henry@poydar.com
|
18
18
|
executables: []
|
19
19
|
|