hpoydar-chronic_duration 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/README.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
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
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.
5
+ The reverse can also be accomplished with the output method. So pass in seconds and you can get strings like 4 mins 31.51 secs (default format), 4h 3m 30s, or 4:01:29.
6
6
 
7
7
  == Installation
8
8
 
@@ -17,6 +17,12 @@ The reverse can also be accomplished with the output method. So pass in seconds
17
17
  => 270
18
18
  >> ChronicDuration.output(270)
19
19
  => 4 mins 30 secs
20
+ >> ChronicDuration.output(270, :short)
21
+ => 4m 30s
22
+ >> ChronicDuration.output(270, :long)
23
+ => 4 minutes 30 seconds
24
+ >> ChronicDuration.output(270, :chrono)
25
+ => 4:30
20
26
 
21
27
  Nil is returned if the string can't be parsed
22
28
 
@@ -35,7 +41,8 @@ Examples of parse-able strings:
35
41
 
36
42
  == TODO
37
43
 
38
- * Benchmark and optimize
39
- * Context specific matching (E.g., for '4m30s', assume 'm' is minutes)
44
+ * Benchmark, optimize
45
+ * Context specific matching (E.g., for '4m30s', assume 'm' is minutes not months)
40
46
  * Smartly parse vacation-like durations (E.g., '4 days and 3 nights')
41
- * Allow alternative formatting for output
47
+ * :chrono output option should probably change to something like 4 days 4:00:12 instead of 4:04:00:12
48
+ * Correct rdoc whine on gem install
@@ -7,10 +7,12 @@ module ChronicDuration
7
7
  end
8
8
 
9
9
  # Refactor, DRY up, make recursive
10
- def output(seconds)
10
+ def output(seconds, opts = {})
11
+
12
+ opts[:format] ||= :default
11
13
 
12
14
  years = months = days = hours = minutes = 0
13
-
15
+
14
16
  if seconds >= 60
15
17
  minutes = (seconds / 60).to_i
16
18
  seconds = seconds % 60
@@ -32,28 +34,56 @@ module ChronicDuration
32
34
  end
33
35
  end
34
36
 
37
+ joiner = ' '
38
+ process = nil
39
+
40
+ case opts[:format]
41
+ when :short
42
+ dividers = {
43
+ :years => 'y', :months => 'm', :days => 'd', :hours => 'h', :minutes => 'm', :seconds => 's' }
44
+ when :default
45
+ dividers = {
46
+ :years => ' yr', :months => ' mo', :days => ' day', :hours => ' hr', :minutes => ' min', :seconds => ' sec',
47
+ :pluralize => true }
48
+ when :long
49
+ dividers = {
50
+ :years => ' year', :months => ' month', :days => ' day', :hours => ' hour', :minutes => ' minute', :seconds => ' second',
51
+ :pluralize => true }
52
+ when :chrono
53
+ dividers = {
54
+ :years => ':', :months => ':', :days => ':', :hours => ':', :minutes => ':', :seconds => ':', :keep_zero => true }
55
+ process = lambda do |str|
56
+ # Pad zeros
57
+ # Get rid of lead off times if they are zero
58
+ # Get rid of lead off zero
59
+ # Get rid of trailing :
60
+ str.gsub(/\b\d\b/) { |d| ("%02d" % d) }.gsub(/^(00:)+/, '').gsub(/^0/, '').gsub(/:$/, '')
61
+ end
62
+ joiner = ''
63
+ end
64
+
35
65
  result = []
66
+ [:years, :months, :days, :hours, :minutes, :seconds].each do |t|
67
+ result << humanize_time_unit( eval(t.to_s), dividers[t], dividers[:pluralize], dividers[:keep_zero] )
68
+ end
36
69
 
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
70
+ result = result.join(joiner).squeeze(' ').strip
71
+
72
+ if process
73
+ result = process.call(result)
74
+ end
75
+
76
+ result.length == 0 ? nil : result
46
77
 
47
- result
48
78
  end
49
79
 
50
80
  private
51
81
 
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
82
+ def humanize_time_unit(number, unit, pluralize, keep_zero)
83
+ return '' if number == 0 && !keep_zero
84
+ res = "#{number}#{unit}"
85
+ # A poor man's pluralizer
86
+ res << 's' if !(number == 1) && pluralize
57
87
  res
58
88
  end
59
89
 
@@ -52,24 +52,56 @@ describe ChronicDuration, '.output' do
52
52
  ChronicDuration.parse('gobblygoo').should be_nil
53
53
  end
54
54
 
55
-
56
55
  @exemplars = {
57
- '1 min 20 secs' => 60 + 20,
58
- '1 min 20.51 secs' => 60 + 20.51,
59
- '3 mins 20.51 secs' => 3 * 60 + 20.51,
60
- '4 hrs 1 min 1 sec' => 4 * 3600 + 60 + 1,
61
- '3 mins 4 secs' => 3 * 60 + 4,
62
- '2 hrs 20 mins' => 2 * 3600 + 20 * 60,
63
- '1 mo 1 day' => 1 * 30 * 24 * 3600 + 24 * 3600,
64
- '6 mos 1 day' => 6 * 30 * 24 * 3600 + 24 * 3600,
65
- '6 mos 2 days' => 6 * 30 * 24 * 3600 + 2 * 24 * 3600,
66
- '2 hrs 30 mins' => 2.5 * 3600
56
+ (60 + 20) =>
57
+ {
58
+ :short => '1m 20s',
59
+ :default => '1 min 20 secs',
60
+ :long => '1 minute 20 seconds',
61
+ :chrono => '1:20'
62
+ },
63
+ (60 + 20.51) =>
64
+ {
65
+ :short => '1m 20.51s',
66
+ :default => '1 min 20.51 secs',
67
+ :long => '1 minute 20.51 seconds',
68
+ :chrono => '1:20.51'
69
+ },
70
+ (4 * 3600 + 60 + 1) =>
71
+ {
72
+ :short => '4h 1m 1s',
73
+ :default => '4 hrs 1 min 1 sec',
74
+ :long => '4 hours 1 minute 1 second',
75
+ :chrono => '4:01:01'
76
+ },
77
+ (2 * 3600 + 20 * 60) =>
78
+ {
79
+ :short => '2h 20m',
80
+ :default => '2 hrs 20 mins',
81
+ :long => '2 hours 20 minutes',
82
+ :chrono => '2:20'
83
+ },
84
+ (2 * 3600 + 20 * 60) =>
85
+ {
86
+ :short => '2h 20m',
87
+ :default => '2 hrs 20 mins',
88
+ :long => '2 hours 20 minutes',
89
+ :chrono => '2:20:00'
90
+ },
91
+ (6 * 30 * 24 * 3600 + 24 * 3600) =>
92
+ {
93
+ :short => '6m 1d',
94
+ :default => '6 mos 1 day',
95
+ :long => '6 months 1 day',
96
+ :chrono => '6:01:00:00:00' # Yuck. FIXME
97
+ }
67
98
  }
68
99
 
69
-
70
100
  @exemplars.each do |k, v|
71
- it "should properly output a duration of #{v}" do
72
- ChronicDuration.output(v).should == k
101
+ v.each do |key, val|
102
+ it "should properly output a duration of #{k} seconds as #{val} using the #{key.to_s} format option" do
103
+ ChronicDuration.output(k, :format => key).should == val
104
+ end
73
105
  end
74
106
  end
75
107
 
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.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henry Poydar
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-01-14 00:00:00 -08:00
12
+ date: 2009-01-16 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -23,7 +23,7 @@ extra_rdoc_files: []
23
23
 
24
24
  files:
25
25
  - lib/chronic_duration.rb
26
- - LICENSE
26
+ - MIT-LICENSE
27
27
  - Rakefile
28
28
  - README.rdoc
29
29
  has_rdoc: true