xduration 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/.travis.yml +10 -0
- data/CHANGELOG +8 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +100 -0
- data/Rakefile +14 -0
- data/config/locales/duration/da.yml +16 -0
- data/config/locales/duration/pt.yml +16 -0
- data/lib/duration/fixnum.rb +11 -0
- data/lib/duration/macros.rb +2 -0
- data/lib/duration/mongoid.rb +36 -0
- data/lib/duration/numeric.rb +60 -0
- data/lib/duration/rails/engine.rb +9 -0
- data/lib/duration/time_units/day.rb +12 -0
- data/lib/duration/time_units/decade.rb +11 -0
- data/lib/duration/time_units/hour.rb +12 -0
- data/lib/duration/time_units/minute.rb +12 -0
- data/lib/duration/time_units/month.rb +12 -0
- data/lib/duration/time_units/second.rb +11 -0
- data/lib/duration/time_units/week.rb +11 -0
- data/lib/duration/time_units/year.rb +11 -0
- data/lib/duration/time_units.rb +3 -0
- data/lib/duration/version.rb +3 -0
- data/lib/duration.rb +240 -0
- data/lib/xduration.rb +2 -0
- data/test/fixtures/locales/da.yml +16 -0
- data/test/fixtures/locales/pt.yml +16 -0
- data/test/helper.rb +15 -0
- data/test/test_duration.rb +180 -0
- data/test/test_i18n.rb +82 -0
- data/test/test_macros.rb +168 -0
- data/test/test_mongoid.rb +70 -0
- data/xduration.gemspec +32 -0
- metadata +229 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
## 0.2.2
|
2
|
+
|
3
|
+
* Renamed to 'xduration'
|
4
|
+
* Added months (30 days) and years (365.25 days)
|
5
|
+
* Added month and year I18n support
|
6
|
+
* Added Rails engine in order to support auto-load of duration locale files
|
7
|
+
* Added numeric macros
|
8
|
+
* Added TimeUnit wrappers such as: Hours, Weeks etc.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jose Peleteiro
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
xduration
|
2
|
+
=============
|
3
|
+
|
4
|
+
Duration is an immutable type that represents some amount of time with accuracy in seconds.
|
5
|
+
|
6
|
+
A lot of the code and inspirations is borrowed from [duration](http://rubyforge.org/projects/duration)
|
7
|
+
lib, which is a **mutable** Duration type with lot more features but lack of tests.
|
8
|
+
|
9
|
+
|
10
|
+
Features
|
11
|
+
--------
|
12
|
+
|
13
|
+
* Representation of time in weeks, days, hours, minutes and seconds.
|
14
|
+
* Construtor can receive the amount of time in seconds or a Hash with unit and amount of time.
|
15
|
+
* Format method to display the time with i18n support.
|
16
|
+
* Mongoid serialization support. Use `require 'duration/mongoid'`.
|
17
|
+
* Tested on mri 1.8.7, ree 1.8.7, mri 1.9.2, jruby and rubinius. Kudos to rvm!
|
18
|
+
|
19
|
+
Extras
|
20
|
+
---------
|
21
|
+
|
22
|
+
### Macros
|
23
|
+
|
24
|
+
`require 'duration/macros'`
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
1.day + 4.hours
|
28
|
+
10.am
|
29
|
+
```
|
30
|
+
|
31
|
+
`require 'duration/time_units'`
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
weeks = Weeks.new(6)
|
35
|
+
years = Years.new(6)
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
Show me the code
|
40
|
+
----------------
|
41
|
+
|
42
|
+
### constructor
|
43
|
+
|
44
|
+
Duration.new(100) => #<Duration: minutes=1, seconds=40, total=100>
|
45
|
+
Duration.new(:hours => 5, :minutes => 70) => #<Duration: hours=6, minutes=10, total=22200>
|
46
|
+
|
47
|
+
### format
|
48
|
+
|
49
|
+
Duration.new(:weeks => 3, :days => 1).format("%w %~w and %d %~d") => "3 weeks and 1 day"
|
50
|
+
Duration.new(:weeks => 1, :days => 20).format("%w %~w and %d %~d") => "3 weeks and 6 days"
|
51
|
+
|
52
|
+
### iso 8601 [more info](http://en.wikipedia.org/wiki/ISO_8601#Durations)
|
53
|
+
|
54
|
+
Duration.new(:weeks => 1, :days => 20).iso8601 => "P3W6DT0H0M0S"
|
55
|
+
|
56
|
+
### Mongoid support
|
57
|
+
The current version of this gem supports Mongoid >= [2.1.0](https://github.com/mongoid/mongoid).
|
58
|
+
|
59
|
+
require 'duration/mongoid'
|
60
|
+
|
61
|
+
class MyModel
|
62
|
+
include Mongoid::Document
|
63
|
+
field :duration, type => Duration
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
Note on Patches/Pull Requests
|
68
|
+
-----------------------------
|
69
|
+
|
70
|
+
* Fork the project.
|
71
|
+
* Make your feature addition or bug fix.
|
72
|
+
* Add tests for it. This is important so I don't break it in a
|
73
|
+
future version unintentionally.
|
74
|
+
* Commit, do not mess with rakefile, version, or history.
|
75
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
76
|
+
* Send me a pull request. Bonus points for topic branches.
|
77
|
+
|
78
|
+
|
79
|
+
License
|
80
|
+
---------
|
81
|
+
Copyright (c) 2010 Jose Peleteiro
|
82
|
+
|
83
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
84
|
+
a copy of this software and associated documentation files (the
|
85
|
+
"Software"), to deal in the Software without restriction, including
|
86
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
87
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
88
|
+
permit persons to whom the Software is furnished to do so, subject to
|
89
|
+
the following conditions:
|
90
|
+
|
91
|
+
The above copyright notice and this permission notice shall be
|
92
|
+
included in all copies or substantial portions of the Software.
|
93
|
+
|
94
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
95
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
96
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
97
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
98
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
99
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
100
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
task :default => :test
|
5
|
+
|
6
|
+
require 'rake/testtask'
|
7
|
+
Rake::TestTask.new(:test) do |test|
|
8
|
+
test.libs << 'lib' << 'test'
|
9
|
+
test.pattern = 'test/**/test_*.rb'
|
10
|
+
test.verbose = true
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'yard'
|
14
|
+
YARD::Rake::YardocTask.new
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../duration"
|
2
|
+
require "mongoid/fields"
|
3
|
+
|
4
|
+
# Mongoid serialization support for Duration type.
|
5
|
+
module Mongoid
|
6
|
+
module Fields
|
7
|
+
class Duration
|
8
|
+
include Mongoid::Fields::Serializable
|
9
|
+
|
10
|
+
# Deserialize a Duration given the amount of seconds stored by Mongodb
|
11
|
+
#
|
12
|
+
# @param [Integer, nil] duration in seconds
|
13
|
+
# @return [Duration] deserialized Duration
|
14
|
+
def deserialize(seconds)
|
15
|
+
return if !seconds
|
16
|
+
::Duration.new(seconds)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Serialize a Duration or a Hash (with duration units) or a amount of seconds to
|
20
|
+
# a BSON serializable type.
|
21
|
+
#
|
22
|
+
# @param [Duration, Hash, Integer] value
|
23
|
+
# @return [Integer] duration in seconds
|
24
|
+
def serialize(value)
|
25
|
+
return if value.blank?
|
26
|
+
if value.is_a?(Hash)
|
27
|
+
value.delete_if{|k, v| v.blank? || !::Duration::UNITS.include?(k.to_sym)}
|
28
|
+
return if value.blank?
|
29
|
+
::Duration.new(value).to_i
|
30
|
+
elsif value.respond_to?(:to_i)
|
31
|
+
value.to_i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'duration/time_units'
|
2
|
+
|
3
|
+
class Numeric
|
4
|
+
def duration
|
5
|
+
Duration.new self
|
6
|
+
end
|
7
|
+
|
8
|
+
def dyears
|
9
|
+
self == 1 ? Year.new : Years.new(self)
|
10
|
+
end
|
11
|
+
def dyear
|
12
|
+
self.dyears
|
13
|
+
end
|
14
|
+
|
15
|
+
def dmonths
|
16
|
+
self == 1 ? Month.new : Months.new(self)
|
17
|
+
end
|
18
|
+
def dmonth
|
19
|
+
self.dmonths
|
20
|
+
end
|
21
|
+
|
22
|
+
def dweeks
|
23
|
+
self == 1 ? Week.new : Weeks.new(self)
|
24
|
+
end
|
25
|
+
def dweek
|
26
|
+
self.dweeks
|
27
|
+
end
|
28
|
+
|
29
|
+
def ddays
|
30
|
+
self == 1 ? Day.new : Days.new(self)
|
31
|
+
end
|
32
|
+
def dday
|
33
|
+
self.ddays
|
34
|
+
end
|
35
|
+
|
36
|
+
def dhours
|
37
|
+
self == 1 ? Hour.new : Hours.new(self)
|
38
|
+
end
|
39
|
+
def dhour
|
40
|
+
self.dhours
|
41
|
+
end
|
42
|
+
|
43
|
+
def dminutes
|
44
|
+
self == 1 ? Minute.new : Minutes.new(self)
|
45
|
+
end
|
46
|
+
def dminute
|
47
|
+
self.dminutes
|
48
|
+
end
|
49
|
+
|
50
|
+
def dseconds
|
51
|
+
self == 1 ? Second.new : Seconds.new(self)
|
52
|
+
end
|
53
|
+
def dsecond
|
54
|
+
self.dseconds
|
55
|
+
end
|
56
|
+
|
57
|
+
def is_multiple_of?(num)
|
58
|
+
self % num == 0
|
59
|
+
end
|
60
|
+
end
|
data/lib/duration.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'i18n'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
|
5
|
+
if defined?(Rails) && Rails::VERSION::STRING >= '3.1'
|
6
|
+
require 'duration/rails/engine'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Duration objects are simple mechanisms that allow you to operate on durations
|
10
|
+
# of time. They allow you to know how much time has passed since a certain
|
11
|
+
# point in time, or they can tell you how much time something is (when given as
|
12
|
+
# seconds) in different units of time measurement. Durations would particularly
|
13
|
+
# be useful for those scripts or applications that allow you to know the uptime
|
14
|
+
# of themselves or perhaps provide a countdown until a certain event.
|
15
|
+
class Duration
|
16
|
+
include Comparable
|
17
|
+
|
18
|
+
UNITS = [:seconds, :minutes, :hours, :days, :weeks, :months, :years]
|
19
|
+
|
20
|
+
MULTIPLES = {:seconds => 1,
|
21
|
+
:minutes => 60,
|
22
|
+
:hours => 3600,
|
23
|
+
:days => 86400,
|
24
|
+
:weeks => 604800,
|
25
|
+
:months => 2592000, # 30 days
|
26
|
+
:years => 31557600, # 365.25 days
|
27
|
+
:second => 1,
|
28
|
+
:minute => 60,
|
29
|
+
:hour => 3600,
|
30
|
+
:day => 86400,
|
31
|
+
:week => 604800,
|
32
|
+
:month => 2592000,
|
33
|
+
:year => 31557600}
|
34
|
+
|
35
|
+
attr_reader :years, :months, :weeks, :days, :hours, :minutes, :seconds, :total
|
36
|
+
|
37
|
+
# Initialize a duration. 'args' can be a hash or anything else. If a hash is
|
38
|
+
# passed, it will be scanned for a key=>value pair of time units such as those
|
39
|
+
# listed in the Duration::UNITS array or Duration::MULTIPLES hash.
|
40
|
+
#
|
41
|
+
# If anything else except a hash is passed, #to_i is invoked on that object
|
42
|
+
# and expects that it return the number of seconds desired for the duration.
|
43
|
+
def initialize(args = 0)
|
44
|
+
if args.kind_of?(Hash)
|
45
|
+
@seconds = 0
|
46
|
+
MULTIPLES.each do |unit, multiple|
|
47
|
+
unit = unit.to_sym
|
48
|
+
@seconds += args[unit].to_i * multiple if args.key?(unit)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
@seconds = args.to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
calculate!
|
55
|
+
end
|
56
|
+
|
57
|
+
# Compare this duration to another (or objects that respond to #to_i)
|
58
|
+
def <=>(other)
|
59
|
+
return false unless other.is_a?(Duration)
|
60
|
+
@total <=> other.to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
def +(other)
|
64
|
+
Duration.new(@total + other.to_i)
|
65
|
+
end
|
66
|
+
|
67
|
+
def -(other)
|
68
|
+
Duration.new(@total - other.to_i)
|
69
|
+
end
|
70
|
+
|
71
|
+
def *(other)
|
72
|
+
Duration.new(@total * other.to_i)
|
73
|
+
end
|
74
|
+
|
75
|
+
def /(other)
|
76
|
+
Duration.new(@total / other.to_i)
|
77
|
+
end
|
78
|
+
|
79
|
+
def %(other)
|
80
|
+
Duration.new(@total % other.to_i)
|
81
|
+
end
|
82
|
+
|
83
|
+
%w(minutes hours days).each do |meth|
|
84
|
+
define_method("total_#{meth}") { @total / MULTIPLES[meth.to_sym] }
|
85
|
+
end
|
86
|
+
|
87
|
+
# Formats a duration in ISO8601.
|
88
|
+
# @see http://en.wikipedia.org/wiki/ISO_8601#Durations
|
89
|
+
def iso8601
|
90
|
+
output = 'P'
|
91
|
+
|
92
|
+
output << "#{weeks}W" if weeks > 0
|
93
|
+
output << "#{days}D" if days > 0
|
94
|
+
if seconds > 0 || minutes > 0 || hours > 0
|
95
|
+
output << 'T'
|
96
|
+
output << "#{hours}H" if hours > 0
|
97
|
+
output << "#{minutes}M" if minutes > 0
|
98
|
+
output << "#{seconds}S" if seconds > 0
|
99
|
+
end
|
100
|
+
|
101
|
+
output
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return true if total is 0
|
105
|
+
def blank?
|
106
|
+
@total == 0
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return true if total different than 0
|
110
|
+
def present?
|
111
|
+
!blank?
|
112
|
+
end
|
113
|
+
|
114
|
+
# Format a duration into a human-readable string.
|
115
|
+
#
|
116
|
+
# %w => weeks
|
117
|
+
# %d => days
|
118
|
+
# %h => hours
|
119
|
+
# %m => minutes
|
120
|
+
# %s => seconds
|
121
|
+
# %td => total days
|
122
|
+
# %th => total hours
|
123
|
+
# %tm => total minutes
|
124
|
+
# %ts => total seconds
|
125
|
+
# %t => total seconds
|
126
|
+
# %H => zero-padded hours
|
127
|
+
# %M => zero-padded minutes
|
128
|
+
# %S => zero-padded seconds
|
129
|
+
# %~s => locale-dependent "seconds" terminology
|
130
|
+
# %~m => locale-dependent "minutes" terminology
|
131
|
+
# %~h => locale-dependent "hours" terminology
|
132
|
+
# %~d => locale-dependent "days" terminology
|
133
|
+
# %~w => locale-dependent "weeks" terminology
|
134
|
+
# %tdu => total days with locale-dependent unit
|
135
|
+
# %thu => total hours with locale-dependent unit
|
136
|
+
# %tmu => total minutes with locale-dependent unit
|
137
|
+
# %tsu => total seconds with locale-dependent unit
|
138
|
+
#
|
139
|
+
# You can also use the I18n support.
|
140
|
+
# The %~s, %~m, %~h, %~d and %~w can be translated with I18n.
|
141
|
+
# If you are using Ruby on Rails, the support is ready out of the box, so just change your locale file. Otherwise you can try:
|
142
|
+
#
|
143
|
+
# I18n.load_path << "path/to/your/locale"
|
144
|
+
# I18n.locale = :your_locale
|
145
|
+
#
|
146
|
+
# And you must use the following structure (example) for your locale file:
|
147
|
+
# pt:
|
148
|
+
# ruby_duration:
|
149
|
+
# second: segundo
|
150
|
+
# seconds: segundos
|
151
|
+
# minute: minuto
|
152
|
+
# minutes: minutos
|
153
|
+
# hour: hora
|
154
|
+
# hours: horas
|
155
|
+
# day: dia
|
156
|
+
# days: dias
|
157
|
+
# week: semana
|
158
|
+
# weeks: semanas
|
159
|
+
#
|
160
|
+
def format(format_str)
|
161
|
+
identifiers = {
|
162
|
+
'y' => @years,
|
163
|
+
'o' => @months,
|
164
|
+
'w' => @weeks,
|
165
|
+
'd' => @days,
|
166
|
+
'h' => @hours,
|
167
|
+
'm' => @minutes,
|
168
|
+
's' => @seconds,
|
169
|
+
'ty' => Proc.new { total_years },
|
170
|
+
'to' => Proc.new { total_months },
|
171
|
+
'tw' => Proc.new { total_weeks },
|
172
|
+
'td' => Proc.new { total_days },
|
173
|
+
'th' => Proc.new { total_hours },
|
174
|
+
'tm' => Proc.new { total_minutes },
|
175
|
+
'ts' => @total,
|
176
|
+
't' => @total,
|
177
|
+
'H' => @hours.to_s.rjust(2, '0'),
|
178
|
+
'M' => @minutes.to_s.rjust(2, '0'),
|
179
|
+
'S' => @seconds.to_s.rjust(2, '0'),
|
180
|
+
'~s' => i18n_for(:second),
|
181
|
+
'~m' => i18n_for(:minute),
|
182
|
+
'~h' => i18n_for(:hour),
|
183
|
+
'~d' => i18n_for(:day),
|
184
|
+
'~w' => i18n_for(:week),
|
185
|
+
'~o' => i18n_for(:month),
|
186
|
+
'~y' => i18n_for(:year),
|
187
|
+
'tyr'=> Proc.new { "#{total_years} #{i18n_for(:total_year)}"},
|
188
|
+
'tmo'=> Proc.new { "#{total_months} #{i18n_for(:total_month)}"},
|
189
|
+
'twk'=> Proc.new { "#{total_weeks} #{i18n_for(:total_week)}"},
|
190
|
+
'tdu'=> Proc.new { "#{total_days} #{i18n_for(:total_day)}"},
|
191
|
+
'thu'=> Proc.new { "#{total_hours} #{i18n_for(:total_hour)}"},
|
192
|
+
'tmu'=> Proc.new { "#{total_minutes} #{i18n_for(:total_minute)}"},
|
193
|
+
'tsu'=> Proc.new { "#{total} #{i18n_for(:total)}"}
|
194
|
+
}
|
195
|
+
|
196
|
+
format_str.gsub(/%?%(y|o|w|d|h|m|s|t([ydhms]u?)?|H|M|S|~(?:s|m|h|d|w|o|y))/) do |match|
|
197
|
+
match['%%'] ? match : (identifiers[match[1..-1]].class == Proc ? identifiers[match[1..-1]].call : identifiers[match[1..-1]])
|
198
|
+
end.gsub('%%', '%')
|
199
|
+
end
|
200
|
+
|
201
|
+
alias_method :to_i, :total
|
202
|
+
alias_method :strftime, :format
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
# Calculates the duration from seconds and figures out what the actual
|
207
|
+
# durations are in specific units. This method is called internally, and
|
208
|
+
# does not need to be called by user code.
|
209
|
+
def calculate!
|
210
|
+
multiples = [MULTIPLES[:years], MULTIPLES[:months], MULTIPLES[:weeks], MULTIPLES[:days], MULTIPLES[:hours], MULTIPLES[:minutes], MULTIPLES[:seconds]]
|
211
|
+
units = []
|
212
|
+
@total = @seconds.to_f.round
|
213
|
+
multiples.inject(@total) do |total, multiple|
|
214
|
+
# Divide into largest unit
|
215
|
+
units << total / multiple
|
216
|
+
total % multiple # The remainder will be divided as the next largest
|
217
|
+
end
|
218
|
+
|
219
|
+
# Gather the divided units
|
220
|
+
@years, @months, @weeks, @days, @hours, @minutes, @seconds = units
|
221
|
+
end
|
222
|
+
|
223
|
+
def i18n_for(singular)
|
224
|
+
if singular == :total
|
225
|
+
fn_name = :total
|
226
|
+
singular = :second
|
227
|
+
plural = 'seconds'
|
228
|
+
elsif singular.to_s.start_with?('total_')
|
229
|
+
fn_name = "#{singular}s"
|
230
|
+
singular = singular.to_s['total_'.length..-1]
|
231
|
+
plural = "#{singular}s"
|
232
|
+
else
|
233
|
+
plural = "#{singular}s"
|
234
|
+
fn_name = plural
|
235
|
+
end
|
236
|
+
label = send(fn_name) == 1 ? singular : plural
|
237
|
+
|
238
|
+
I18n.t(label, :scope => :ruby_duration, :default => label.to_s)
|
239
|
+
end
|
240
|
+
end
|