dotiw 5.3.2 → 5.5.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/.github/workflows/ruby.yml +17 -16
- data/Appraisals +12 -4
- data/CHANGELOG.md +14 -0
- data/CODEOWNERS +2 -0
- data/README.markdown +36 -0
- data/dotiw.gemspec +3 -0
- data/gemfiles/{rails_4.gemfile → rails_7.0.gemfile} +2 -1
- data/gemfiles/rails_7.1.gemfile +11 -0
- data/gemfiles/rails_7.2.gemfile +11 -0
- data/lib/dotiw/locale/dz.yml +60 -0
- data/lib/dotiw/locale/ru.yml +9 -9
- data/lib/dotiw/methods.rb +116 -17
- data/lib/dotiw/time_hash.rb +5 -3
- data/lib/dotiw/version.rb +1 -1
- data/lib/dotiw.rb +1 -1
- data/spec/lib/dotiw_spec.rb +89 -13
- data/spec/lib/i18n/dz.yml +21 -0
- data/spec/lib/i18n/ru.yml +18 -0
- metadata +52 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 32864f97b3b06dc77f8c793e11a5b17b1d2af506bdfac0c559354f3e4eef7998
|
|
4
|
+
data.tar.gz: 20efed42fb0802a836f078f2791d78e7b863005b73780243ad4867bbf653103e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6bb97a0d7bc860b57432dc81cb3d8a7921c6364c5271db648d30984164f26d6f4003e21de28252f958294960df1b0270cc4fbf83ae7602be23096829404ee2fe
|
|
7
|
+
data.tar.gz: e2d4f70428937b7e5c409666612dd7aefbe63e71d884a3738b240c222fc2f36a8df7a66b83fa4d52fef96cd27e7edd3a9fdecb15e497fa46853e9b3922f83663
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
name: Ruby
|
|
2
2
|
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- master
|
|
7
|
-
pull_request:
|
|
8
|
-
branches:
|
|
9
|
-
- master
|
|
3
|
+
on: [push, pull_request]
|
|
10
4
|
|
|
11
5
|
jobs:
|
|
12
6
|
build:
|
|
@@ -15,19 +9,26 @@ jobs:
|
|
|
15
9
|
fail-fast: false
|
|
16
10
|
matrix:
|
|
17
11
|
include:
|
|
18
|
-
- ruby-version:
|
|
19
|
-
- ruby-version:
|
|
20
|
-
- ruby-version: 2
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- ruby-version: 2.
|
|
12
|
+
- ruby-version: 3.4
|
|
13
|
+
- ruby-version: 3.3
|
|
14
|
+
- ruby-version: 3.2
|
|
15
|
+
- ruby-version: 3.1
|
|
16
|
+
- ruby-version: 3.0
|
|
17
|
+
- ruby-version: 2.7
|
|
18
|
+
- ruby-version: 2.7
|
|
24
19
|
gemfile: gemfiles/rails_5.0.gemfile
|
|
25
|
-
- ruby-version: 2.
|
|
20
|
+
- ruby-version: 2.7
|
|
26
21
|
gemfile: gemfiles/rails_5.1.gemfile
|
|
27
|
-
- ruby-version: 2.
|
|
22
|
+
- ruby-version: 2.7
|
|
28
23
|
gemfile: gemfiles/rails_5.2.gemfile
|
|
29
|
-
- ruby-version:
|
|
24
|
+
- ruby-version: 3.4
|
|
30
25
|
gemfile: gemfiles/rails_6.0.gemfile
|
|
26
|
+
- ruby-version: 3.4
|
|
27
|
+
gemfile: gemfiles/rails_7.0.gemfile
|
|
28
|
+
- ruby-version: 3.4
|
|
29
|
+
gemfile: gemfiles/rails_7.1.gemfile
|
|
30
|
+
- ruby-version: 3.4
|
|
31
|
+
gemfile: gemfiles/rails_7.2.gemfile
|
|
31
32
|
steps:
|
|
32
33
|
- uses: actions/checkout@v2
|
|
33
34
|
- name: Set up Ruby
|
data/Appraisals
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
appraise 'rails_4' do
|
|
2
|
-
gem 'rails', '~> 4.0'
|
|
3
|
-
end
|
|
4
|
-
|
|
5
1
|
appraise 'rails_5.0' do
|
|
6
2
|
gem 'rails', '~> 5.0.0'
|
|
7
3
|
end
|
|
@@ -17,3 +13,15 @@ end
|
|
|
17
13
|
appraise 'rails_6.0' do
|
|
18
14
|
gem 'rails', '~> 6.0.0'
|
|
19
15
|
end
|
|
16
|
+
|
|
17
|
+
appraise 'rails_7.0' do
|
|
18
|
+
gem 'rails', '~> 7.0.0'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
appraise 'rails_7.1' do
|
|
22
|
+
gem 'rails', '~> 7.1.0'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
appraise 'rails_7.2' do
|
|
26
|
+
gem 'rails', '~> 7.2.0'
|
|
27
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 5.4.0 (Next)
|
|
2
|
+
|
|
3
|
+
* [#131](https://github.com/radar/distance_of_time_in_words/pull/131): Deprecates `highest_measure_only`. Adds alternate form of `highest_measures` option to permit rounding up whatever part of the duration was previously silently discarded - [@seansfkelley](https://github.com/seansfkelley).
|
|
4
|
+
* [#133](https://github.com/radar/distance_of_time_in_words/pull/133): Test on Ruby 3.0 and 3.1 - [@dblock](https://github.com/dblock).
|
|
5
|
+
* [#134](https://github.com/radar/distance_of_time_in_words/pull/134): Add support for Dzongkha, the National language of Bhutan - [@KinWang-2013](https://github.com/KinWang-2013).
|
|
6
|
+
* [#135](https://github.com/radar/distance_of_time_in_words/pull/135): Add support for Ruby 2.7 and 3.2, removed support for ruby 2.4, 2.5, 2.6 and Rails 4 - [@KinWang-2013](https://github.com/KinWang-2013).
|
|
7
|
+
* [#136](https://github.com/radar/distance_of_time_in_words/pull/136): Add support for Rails 7 - [@KinWang-2013](https://github.com/KinWang-2013).
|
|
8
|
+
* [#139](https://github.com/radar/distance_of_time_in_words/pull/139): Fix bug with pluralization of Russian translations for numbers ending in 1 - [bitberry-dev](https://github.com/bitberry-dev).
|
|
9
|
+
* Your contribution here.
|
|
10
|
+
|
|
11
|
+
## 5.3.3 (2022/04/25)
|
|
12
|
+
|
|
13
|
+
* [#128](https://github.com/radar/distance_of_time_in_words/pull/128): Adds support for numeric values for both the `from_time` and `to_time` arguments in the `#distance_of_time_in_words` helper - [@bjedrocha](https://github.com/bjedrocha).
|
|
14
|
+
|
|
1
15
|
## 5.3.2 (2021/11/08)
|
|
2
16
|
|
|
3
17
|
* [#126](https://github.com/radar/distance_of_time_in_words/pull/126): Fixes `#distance_of_time_in_words_to_now` with `vague: true` when supplied without `include_seconds` argument - [@mozcomp](https://github.com/mozcomp).
|
data/CODEOWNERS
ADDED
data/README.markdown
CHANGED
|
@@ -58,6 +58,22 @@ Better than "about 1 year", am I right? Of course I am.
|
|
|
58
58
|
=> "1 second"
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
It also supports numeric arguments like the original Rails version:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
>> distance_of_time_in_words(0, 150)
|
|
65
|
+
=> "2 minutes and 30 seconds"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
as an alternative to:
|
|
69
|
+
|
|
70
|
+
```ruby
|
|
71
|
+
>> distance_of_time_in_words(Time.now, Time.now + 2.5.minutes)
|
|
72
|
+
=> "2 minutes and 30 seconds"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This is useful if you're just interested in "stringifying" the length of time. Alternatively, you can use the `#distance_of_time` helper as described [below](#distance\_of\_time).
|
|
76
|
+
|
|
61
77
|
The third argument for this method is whether or not to include seconds. By default this is `false` (because in Rails' `distance_of_time_in_words` it is), you can turn it on though by passing `true` as the third argument:
|
|
62
78
|
|
|
63
79
|
```ruby
|
|
@@ -148,6 +164,8 @@ Culling a whole group of measurements of time:
|
|
|
148
164
|
|
|
149
165
|
#### :highest\_measure\_only
|
|
150
166
|
|
|
167
|
+
> **Deprecated**. Use `highest_measures: 1` instead.
|
|
168
|
+
|
|
151
169
|
For times when Rails `distance_of_time_in_words` is not precise enough and `DOTIW` is too precise. For instance, if you only want to know the highest time part (measure) that elapsed between two dates.
|
|
152
170
|
|
|
153
171
|
```ruby
|
|
@@ -173,6 +191,24 @@ When you want variable precision from `DOTIW`:
|
|
|
173
191
|
=> "1 hour and 1 minute"
|
|
174
192
|
```
|
|
175
193
|
|
|
194
|
+
You can also specify what to do with the extra time with the `remainder` option:
|
|
195
|
+
|
|
196
|
+
```ruby
|
|
197
|
+
>> distance_of_time_in_words(Time.now, Time.now + 1.hour + 1.minute + 1.second, true, highest_measures: { max: 2, remainder: :ceiling })
|
|
198
|
+
=> "1 hour and 2 minutes"
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Valid options for `remainder` are `:floor` (default), `:ceiling` and `:round`. Note that `:round` is best-effort and makes some simplifying assumptions:
|
|
202
|
+
|
|
203
|
+
```ruby
|
|
204
|
+
# Only the next-largest unit is examined, which can unexpectedly round down in some situations.
|
|
205
|
+
>> distance_of_time_in_words(Time.now, Time.now + 1.week + 3.days + 23.hours, true, highest_measures: { remainder: :round })
|
|
206
|
+
=> "1 week"
|
|
207
|
+
# The variability of some measures (like months) is ignored and the shortest duration of that measure is used.
|
|
208
|
+
>> distance_of_time_in_words(Time.now, Time.now + 1.month + 14.days, true, highest_measures: { remainder: :round })
|
|
209
|
+
=> "2 months"
|
|
210
|
+
```
|
|
211
|
+
|
|
176
212
|
#### :words_connector
|
|
177
213
|
|
|
178
214
|
This is an option for `to_sentence`, defaults to ', '.
|
data/dotiw.gemspec
CHANGED
|
@@ -27,6 +27,9 @@ Gem::Specification.new do |s|
|
|
|
27
27
|
s.add_development_dependency 'rake'
|
|
28
28
|
s.add_development_dependency 'rspec', '~> 3.0'
|
|
29
29
|
s.add_development_dependency 'tzinfo', '~> 1.2.7'
|
|
30
|
+
s.add_development_dependency 'mutex_m'
|
|
31
|
+
s.add_development_dependency 'base64'
|
|
32
|
+
s.add_development_dependency 'bigdecimal'
|
|
30
33
|
|
|
31
34
|
s.files = `git ls-files`.split("\n")
|
|
32
35
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
dz:
|
|
2
|
+
datetime:
|
|
3
|
+
dotiw:
|
|
4
|
+
seconds:
|
|
5
|
+
one: སྐར་ཆ་ ༡
|
|
6
|
+
other: "སྐར་ཆ་ %{count}"
|
|
7
|
+
minutes:
|
|
8
|
+
one: སྐར་མ་ ༡
|
|
9
|
+
other: "སྐར་མ་ %{count}"
|
|
10
|
+
hours:
|
|
11
|
+
one: ཆུ་ཚོད་ ༡
|
|
12
|
+
other: "ཆུ་ཚོད་ %{count}"
|
|
13
|
+
days:
|
|
14
|
+
one: ཉིནམ་ ༡
|
|
15
|
+
other: "ཉིནམ་ %{count}"
|
|
16
|
+
weeks:
|
|
17
|
+
one: བདུན༌ཕྲག་ ༡
|
|
18
|
+
other: "བདུན༌ཕྲག་ %{count}"
|
|
19
|
+
months:
|
|
20
|
+
one: ཟླཝ་ ༡
|
|
21
|
+
other: "ཟླཝ་ %{count}"
|
|
22
|
+
years:
|
|
23
|
+
one: ལོ་ ༡
|
|
24
|
+
other: "ལོ་ %{count}"
|
|
25
|
+
less_than_x: "%{distance} ་ལས་ཉུངམ་"
|
|
26
|
+
dotiw_compact:
|
|
27
|
+
seconds:
|
|
28
|
+
one: སྐར་ཆ་ ༡
|
|
29
|
+
other: "སྐར་ཆ་ %{count}"
|
|
30
|
+
minutes:
|
|
31
|
+
one: སྐར་མ་ ༡
|
|
32
|
+
other: "སྐར་མ་ %{count}"
|
|
33
|
+
hours:
|
|
34
|
+
one: ཆུ་ཚོད་ ༡
|
|
35
|
+
other: "ཆུ་ཚོད་ %{count}"
|
|
36
|
+
days:
|
|
37
|
+
one: ཉིནམ་ ༡
|
|
38
|
+
other: "ཉིནམ་ %{count}"
|
|
39
|
+
weeks:
|
|
40
|
+
one: བདུན༌ཕྲག་ ༡
|
|
41
|
+
other: "བདུན༌ཕྲག་ %{count}"
|
|
42
|
+
months:
|
|
43
|
+
one: ཟླཝ་ ༡
|
|
44
|
+
other: "ཟླཝ་ %{count}"
|
|
45
|
+
years:
|
|
46
|
+
one: ལོ་ ༡
|
|
47
|
+
other: "ལོ་ %{count}"
|
|
48
|
+
less_than_x: "%{distance} ་ལས་ཉུངམ"
|
|
49
|
+
words_connector: ""
|
|
50
|
+
two_words_connector: " དང་ "
|
|
51
|
+
last_word_connector: " དང་ "
|
|
52
|
+
about_x_years:
|
|
53
|
+
one: ལོ་ ༡ ་དེ་ཅིག
|
|
54
|
+
any: "ལོ་ %{count} ་དེ་ཅིག"
|
|
55
|
+
over_x_years:
|
|
56
|
+
one: "ལོ་ ༡ ་ལས་ལྷགཔ་ཅིག"
|
|
57
|
+
other: "ལོ་ %{count} ་ལས་ལྷགཔ་ཅིག"
|
|
58
|
+
almost_x_years:
|
|
59
|
+
one: ལོ་ ༡ ་མ་ལྷགཔ་ཅིག
|
|
60
|
+
any: "ལོ་ %{count} ་མ་ལྷགཔ་ཅིག"
|
data/lib/dotiw/locale/ru.yml
CHANGED
|
@@ -39,22 +39,22 @@ ru:
|
|
|
39
39
|
less_than_x: "меньше, чем %{distance}"
|
|
40
40
|
dotiw_compact:
|
|
41
41
|
seconds:
|
|
42
|
-
one:
|
|
42
|
+
one: "%{count}с"
|
|
43
43
|
other: "%{count}с"
|
|
44
44
|
minutes:
|
|
45
|
-
one:
|
|
45
|
+
one: "%{count}м"
|
|
46
46
|
other: "%{count}м"
|
|
47
47
|
hours:
|
|
48
|
-
one:
|
|
48
|
+
one: "%{count}ч"
|
|
49
49
|
other: "%{count}ч"
|
|
50
50
|
days:
|
|
51
|
-
one:
|
|
51
|
+
one: "%{count}д"
|
|
52
52
|
other: "%{count}д"
|
|
53
53
|
weeks:
|
|
54
|
-
one:
|
|
54
|
+
one: "%{count}н"
|
|
55
55
|
other: "%{count}н"
|
|
56
56
|
months:
|
|
57
|
-
one:
|
|
57
|
+
one: "%{count}ме"
|
|
58
58
|
other: "%{count}ме"
|
|
59
59
|
years:
|
|
60
60
|
one: "%{count}г"
|
|
@@ -66,11 +66,11 @@ ru:
|
|
|
66
66
|
two_words_connector: ""
|
|
67
67
|
last_word_connector: ""
|
|
68
68
|
about_x_years:
|
|
69
|
-
one:
|
|
69
|
+
one: "~%{count}г"
|
|
70
70
|
any: "~%{count}г"
|
|
71
71
|
over_x_years:
|
|
72
|
-
one: "
|
|
72
|
+
one: ">%{count}г"
|
|
73
73
|
other: ">%{count}г"
|
|
74
74
|
almost_x_years:
|
|
75
|
-
one:
|
|
75
|
+
one: "~%{count}г"
|
|
76
76
|
any: "~%{count}г"
|
data/lib/dotiw/methods.rb
CHANGED
|
@@ -20,7 +20,9 @@ module DOTIW
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
|
|
23
|
-
|
|
23
|
+
from_time = normalize_distance_of_time_argument_to_time(from_time)
|
|
24
|
+
to_time = normalize_distance_of_time_argument_to_time(to_time)
|
|
25
|
+
from_time, to_time = to_time, from_time if from_time > to_time
|
|
24
26
|
|
|
25
27
|
if include_seconds_or_options.is_a?(Hash)
|
|
26
28
|
options = include_seconds_or_options
|
|
@@ -28,7 +30,8 @@ module DOTIW
|
|
|
28
30
|
options = options.dup
|
|
29
31
|
options[:include_seconds] ||= !!include_seconds_or_options
|
|
30
32
|
end
|
|
31
|
-
|
|
33
|
+
|
|
34
|
+
return distance_of_time(to_time.to_i, options) if from_time.to_i == 0
|
|
32
35
|
|
|
33
36
|
options = options_with_scope(options)
|
|
34
37
|
hash = distance_of_time_in_words_hash(from_time, to_time, options)
|
|
@@ -41,6 +44,41 @@ module DOTIW
|
|
|
41
44
|
|
|
42
45
|
private
|
|
43
46
|
|
|
47
|
+
# How many of each measure is necessary to round up to one of the next-largest measure. Note
|
|
48
|
+
# that for simplicity of implementation, we only check one measure when seeing if we should
|
|
49
|
+
# round up. This means that rounding up days to weeks, for instance, cannot draw the line at 3
|
|
50
|
+
# days and 12 hours, but instead either 3 or 4 (whole) days. Let's not even talk about weeks
|
|
51
|
+
# rounding up to months.
|
|
52
|
+
ROUNDING_THRESHOLDS = {
|
|
53
|
+
seconds: 30,
|
|
54
|
+
minutes: 30,
|
|
55
|
+
hours: 12,
|
|
56
|
+
days: 4,
|
|
57
|
+
weeks: 2,
|
|
58
|
+
months: 6,
|
|
59
|
+
years: Float::INFINITY,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
ROLLUP_THRESHOLDS = {
|
|
63
|
+
seconds: 60,
|
|
64
|
+
minutes: 60,
|
|
65
|
+
hours: 24,
|
|
66
|
+
days: 7,
|
|
67
|
+
weeks: 4, # !!!
|
|
68
|
+
months: 12,
|
|
69
|
+
years: Float::INFINITY,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
def normalize_distance_of_time_argument_to_time(value)
|
|
73
|
+
if value.is_a?(Numeric)
|
|
74
|
+
Time.at(value)
|
|
75
|
+
elsif value.respond_to?(:to_time)
|
|
76
|
+
value.to_time
|
|
77
|
+
else
|
|
78
|
+
raise ArgumentError, "#{value.inspect} can't be converted to a Time value"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
44
82
|
def options_with_scope(options)
|
|
45
83
|
if options.key?(:compact)
|
|
46
84
|
options.merge(scope: DOTIW::DEFAULT_I18N_SCOPE_COMPACT)
|
|
@@ -50,23 +88,29 @@ module DOTIW
|
|
|
50
88
|
end
|
|
51
89
|
|
|
52
90
|
def _display_time_in_words(hash, options = {})
|
|
91
|
+
hash = hash.dup
|
|
92
|
+
|
|
53
93
|
options = options.reverse_merge(
|
|
54
94
|
include_seconds: false
|
|
55
95
|
).symbolize_keys!
|
|
56
96
|
|
|
97
|
+
discarded_hash = {}
|
|
98
|
+
|
|
57
99
|
include_seconds = options.delete(:include_seconds)
|
|
58
|
-
hash.delete(:seconds) if !include_seconds && hash[:minutes]
|
|
100
|
+
discarded_hash[:seconds] = hash.delete(:seconds) if !include_seconds && hash[:minutes]
|
|
59
101
|
|
|
60
102
|
options[:except] = Array.wrap(options[:except]).map!(&:to_sym) if options[:except]
|
|
61
103
|
options[:only] = Array.wrap(options[:only]).map!(&:to_sym) if options[:only]
|
|
62
104
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
(options[:only] && !options[:only].include?(key))
|
|
105
|
+
DOTIW::TimeHash::TIME_FRACTIONS.each do |fraction|
|
|
106
|
+
if options[:except]&.include?(fraction) || (options[:only] && !options[:only].include?(fraction))
|
|
107
|
+
discarded_hash[fraction] = hash.delete fraction
|
|
108
|
+
end
|
|
68
109
|
end
|
|
69
110
|
|
|
111
|
+
hash.delete_if { |key, value| value.nil? || value.zero? }
|
|
112
|
+
discarded_hash.delete_if { |key, value| value.nil? || value.zero? }
|
|
113
|
+
|
|
70
114
|
i18n_scope = options.delete(:scope) || DOTIW::DEFAULT_I18N_SCOPE
|
|
71
115
|
if hash.empty?
|
|
72
116
|
fractions = DOTIW::TimeHash::TIME_FRACTIONS
|
|
@@ -81,16 +125,22 @@ module DOTIW
|
|
|
81
125
|
end
|
|
82
126
|
end
|
|
83
127
|
|
|
84
|
-
output = []
|
|
85
|
-
I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
|
|
86
|
-
output = hash.map { |key, value| locale.t(key, count: value) }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
128
|
options.delete(:except)
|
|
90
129
|
options.delete(:only)
|
|
91
|
-
|
|
92
|
-
highest_measures =
|
|
93
|
-
|
|
130
|
+
|
|
131
|
+
highest_measures = _compute_highest_measures! options
|
|
132
|
+
if highest_measures
|
|
133
|
+
high_entries, low_entries = hash.to_a.partition.with_index { |_, index| index < highest_measures[:max] }
|
|
134
|
+
hash = high_entries.to_h
|
|
135
|
+
discarded_hash.merge! low_entries.to_h
|
|
136
|
+
|
|
137
|
+
_maybe_round! hash, discarded_hash, highest_measures[:remainder]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
phrases = []
|
|
141
|
+
I18n.with_options locale: options[:locale], scope: i18n_scope do |locale|
|
|
142
|
+
phrases = hash.map { |key, value| locale.t(key, count: value) }
|
|
143
|
+
end
|
|
94
144
|
|
|
95
145
|
options[:words_connector] ||= I18n.translate :"#{i18n_scope}.words_connector",
|
|
96
146
|
default: :'support.array.words_connector',
|
|
@@ -102,7 +152,56 @@ module DOTIW
|
|
|
102
152
|
default: :'support.array.last_word_connector',
|
|
103
153
|
locale: options[:locale]
|
|
104
154
|
|
|
105
|
-
|
|
155
|
+
phrases.to_sentence(options.except(:accumulate_on, :compact))
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def _compute_highest_measures!(options)
|
|
159
|
+
highest_measures = options.delete(:highest_measures)
|
|
160
|
+
highest_measures = 1 if options.delete(:highest_measure_only)
|
|
161
|
+
highest_measures = { max: highest_measures } if highest_measures.is_a?(Integer)
|
|
162
|
+
highest_measures = highest_measures.reverse_merge(max: 1, remainder: :floor) if highest_measures
|
|
163
|
+
|
|
164
|
+
highest_measures
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def _maybe_round!(hash, discarded_hash, remainder)
|
|
168
|
+
smallest_measure_index = DOTIW::TimeHash::TIME_FRACTIONS.index hash.to_a.last[0]
|
|
169
|
+
smallest_measure = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index]
|
|
170
|
+
|
|
171
|
+
case remainder
|
|
172
|
+
when :floor
|
|
173
|
+
# Nothing to do.
|
|
174
|
+
when :ceiling
|
|
175
|
+
# We already filtered out zeroes, so non-empty also means non-zero.
|
|
176
|
+
if !discarded_hash.empty?
|
|
177
|
+
hash[smallest_measure] += 1
|
|
178
|
+
_rollup! hash, smallest_measure_index
|
|
179
|
+
end
|
|
180
|
+
when :round
|
|
181
|
+
# If our smallest measure is already the smallest possible measure, there is no next
|
|
182
|
+
# smallest measure to inspect to see if we need to round up.
|
|
183
|
+
return if smallest_measure_index == 0
|
|
184
|
+
|
|
185
|
+
next_smallest_measure = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index - 1]
|
|
186
|
+
if discarded_hash.fetch(next_smallest_measure, 0) >= ROUNDING_THRESHOLDS[next_smallest_measure]
|
|
187
|
+
hash[smallest_measure] += 1
|
|
188
|
+
_rollup! hash, smallest_measure_index
|
|
189
|
+
end
|
|
190
|
+
else
|
|
191
|
+
raise ArgumentError, "unrecognized remainder value #{remainder.inspect}"
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def _rollup!(hash, smallest_measure_index)
|
|
196
|
+
DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index..-1].each_with_index do |fraction, index|
|
|
197
|
+
if hash.fetch(fraction, 0) >= ROLLUP_THRESHOLDS[fraction]
|
|
198
|
+
hash.delete fraction
|
|
199
|
+
next_fraction = DOTIW::TimeHash::TIME_FRACTIONS[smallest_measure_index + index + 1]
|
|
200
|
+
hash[next_fraction] = hash.fetch(next_fraction, 0) + 1
|
|
201
|
+
else
|
|
202
|
+
break
|
|
203
|
+
end
|
|
204
|
+
end
|
|
106
205
|
end
|
|
107
206
|
end
|
|
108
207
|
end
|
data/lib/dotiw/time_hash.rb
CHANGED
|
@@ -43,8 +43,6 @@ module DOTIW
|
|
|
43
43
|
def build_time_hash
|
|
44
44
|
if accumulate_on = options[:accumulate_on]
|
|
45
45
|
accumulate_on = accumulate_on.to_sym
|
|
46
|
-
return build_time_hash if accumulate_on == :years
|
|
47
|
-
|
|
48
46
|
TIME_FRACTIONS.index(accumulate_on).downto(0) { |i| send("build_#{TIME_FRACTIONS[i]}") }
|
|
49
47
|
else
|
|
50
48
|
while distance > 0
|
|
@@ -91,11 +89,15 @@ module DOTIW
|
|
|
91
89
|
def build_months
|
|
92
90
|
build_years_months_weeks_days
|
|
93
91
|
|
|
94
|
-
if (years = output.delete(:years)) > 0
|
|
92
|
+
if options[:accumulate_on]&.to_sym == :months && (years = output.delete(:years)) > 0
|
|
95
93
|
output[:months] += (years * 12)
|
|
96
94
|
end
|
|
97
95
|
end
|
|
98
96
|
|
|
97
|
+
def build_years
|
|
98
|
+
build_years_months_weeks_days
|
|
99
|
+
end
|
|
100
|
+
|
|
99
101
|
def build_years_months_weeks_days
|
|
100
102
|
months = (largest.year - smallest.year) * 12 + (largest.month - smallest.month)
|
|
101
103
|
years, months = months.divmod(12)
|
data/lib/dotiw/version.rb
CHANGED
data/lib/dotiw.rb
CHANGED
data/spec/lib/dotiw_spec.rb
CHANGED
|
@@ -13,10 +13,12 @@ describe 'A better distance_of_time_in_words' do
|
|
|
13
13
|
include DOTIW::Methods
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
START_TIME = '01-08-2009'.to_time
|
|
16
|
+
START_TIME = '01-08-2009'.to_time(:utc)
|
|
17
17
|
|
|
18
18
|
before do
|
|
19
19
|
I18n.locale = :en
|
|
20
|
+
ActiveSupport.to_time_preserves_timezone = :zone
|
|
21
|
+
|
|
20
22
|
allow(Time).to receive(:now).and_return(START_TIME)
|
|
21
23
|
allow(Time.zone).to receive(:now).and_return(START_TIME)
|
|
22
24
|
end
|
|
@@ -101,11 +103,6 @@ describe 'A better distance_of_time_in_words' do
|
|
|
101
103
|
expect(DOTIW.languages.map(&:to_s).sort).to eq languages.sort
|
|
102
104
|
end
|
|
103
105
|
|
|
104
|
-
it 'raises ArgumentError when nil is passed for time' do
|
|
105
|
-
expect { distance_of_time_in_words(nil) }.to raise_error(ArgumentError)
|
|
106
|
-
expect { distance_of_time_in_words(nil, nil) }.to raise_error(ArgumentError)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
106
|
DOTIW.languages.each do |lang|
|
|
110
107
|
context lang do
|
|
111
108
|
YAML.safe_load(
|
|
@@ -118,12 +115,18 @@ describe 'A better distance_of_time_in_words' do
|
|
|
118
115
|
context category do
|
|
119
116
|
fixtures.each_pair do |k, v|
|
|
120
117
|
it v do
|
|
118
|
+
options = {
|
|
119
|
+
locale: lang
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
options[:compact] = true if category.split.include?('compact')
|
|
123
|
+
|
|
121
124
|
expect(
|
|
122
125
|
distance_of_time_in_words(
|
|
123
126
|
START_TIME,
|
|
124
127
|
START_TIME + eval(k),
|
|
125
128
|
true,
|
|
126
|
-
|
|
129
|
+
options
|
|
127
130
|
)
|
|
128
131
|
).to eq(v)
|
|
129
132
|
end
|
|
@@ -170,7 +173,7 @@ describe 'A better distance_of_time_in_words' do
|
|
|
170
173
|
[Time.zone.now, Time.zone.now + 15.days - 1.minute, '14 days, 23 hours, and 59 minutes'],
|
|
171
174
|
[Time.zone.now, Time.zone.now + 29.days - 1.minute, '28 days, 23 hours, and 59 minutes'],
|
|
172
175
|
[Time.zone.now, Time.zone.now + 30.days - 1.minute, '29 days, 23 hours, and 59 minutes'],
|
|
173
|
-
[Time.zone.now, Time.zone.now + 31.
|
|
176
|
+
[Time.zone.now, Time.zone.now + 31.day - 1.minute, '30 days, 23 hours, and 59 minutes'],
|
|
174
177
|
[Time.zone.now, Time.zone.now + 32.days - 1.minute, '31 days, 23 hours, and 59 minutes'],
|
|
175
178
|
[Time.zone.now, Time.zone.now + 33.days - 1.minute, '32 days, 23 hours, and 59 minutes']
|
|
176
179
|
].each do |start, finish, output|
|
|
@@ -216,7 +219,8 @@ describe 'A better distance_of_time_in_words' do
|
|
|
216
219
|
START_TIME + 2.day + 10_000.hour + 10.second,
|
|
217
220
|
:months,
|
|
218
221
|
'13 months, 3 weeks, 1 day, 16 hours, and 10 seconds'],
|
|
219
|
-
['2015-1-15'.to_time, '2016-3-15'.to_time, :months, '14 months']
|
|
222
|
+
['2015-1-15'.to_time, '2016-3-15'.to_time, :months, '14 months'],
|
|
223
|
+
['2015-1-15'.to_time, '2016-3-15'.to_time, :years, '1 year and 2 months']
|
|
220
224
|
].each do |start, finish, accumulator, output|
|
|
221
225
|
it "should be #{output}" do
|
|
222
226
|
expect(distance_of_time_in_words(start, finish, true, accumulate_on: accumulator)).to eq(output)
|
|
@@ -241,6 +245,38 @@ describe 'A better distance_of_time_in_words' do
|
|
|
241
245
|
end
|
|
242
246
|
end
|
|
243
247
|
end
|
|
248
|
+
|
|
249
|
+
describe 'with mixed inputs' do
|
|
250
|
+
# Further backwards compatability with the original rails
|
|
251
|
+
# distance_of_time_in_words helper.
|
|
252
|
+
[
|
|
253
|
+
[0, 2.5.minutes.to_i, '2 minutes and 30 seconds'],
|
|
254
|
+
[10.minutes.to_i, 0, '10 minutes'],
|
|
255
|
+
[0, 24.weeks.to_i, '5 months, 2 weeks, and 1 day'],
|
|
256
|
+
[0, 0, 'less than 1 second'],
|
|
257
|
+
].each do |start, finish, output|
|
|
258
|
+
it "should be #{output}" do
|
|
259
|
+
expect(distance_of_time_in_words(start, finish)).to eq(output)
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
context "of which one or both can't be converted to a Time value" do
|
|
264
|
+
let(:invalid_inputs) do
|
|
265
|
+
[
|
|
266
|
+
[nil, 5.minutes],
|
|
267
|
+
[nil, double(:does_not_respond_to_time)],
|
|
268
|
+
[nil],
|
|
269
|
+
[nil, nil],
|
|
270
|
+
]
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it "should raise an ArgumentError" do
|
|
274
|
+
invalid_inputs.each do |start, finish|
|
|
275
|
+
expect { distance_of_time_in_words(start, finish) }.to raise_error(ArgumentError)
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
244
280
|
end
|
|
245
281
|
|
|
246
282
|
describe 'with output options' do
|
|
@@ -302,7 +338,7 @@ describe 'A better distance_of_time_in_words' do
|
|
|
302
338
|
{ highest_measures: 3 },
|
|
303
339
|
'1 year and 2 weeks'],
|
|
304
340
|
[START_TIME,
|
|
305
|
-
START_TIME + 1.
|
|
341
|
+
START_TIME + 1.day,
|
|
306
342
|
{ only: %i[years months] },
|
|
307
343
|
'less than 1 month'],
|
|
308
344
|
[START_TIME,
|
|
@@ -310,15 +346,55 @@ describe 'A better distance_of_time_in_words' do
|
|
|
310
346
|
{ except: %i[hours minutes seconds] },
|
|
311
347
|
'less than 1 day'],
|
|
312
348
|
[START_TIME,
|
|
313
|
-
START_TIME + 1.
|
|
349
|
+
START_TIME + 1.day,
|
|
314
350
|
{ highest_measures: 1, only: %i[years months] },
|
|
315
|
-
'less than 1 month']
|
|
351
|
+
'less than 1 month'],
|
|
352
|
+
[START_TIME,
|
|
353
|
+
START_TIME + 1.day + 1.hour,
|
|
354
|
+
{ highest_measures: {} },
|
|
355
|
+
'1 day'],
|
|
356
|
+
[START_TIME,
|
|
357
|
+
START_TIME + 1.day + 1.hour,
|
|
358
|
+
{ highest_measures: { remainder: :floor} },
|
|
359
|
+
'1 day'],
|
|
360
|
+
[START_TIME,
|
|
361
|
+
START_TIME + 1.year + 1.minute,
|
|
362
|
+
{ highest_measures: { remainder: :ceiling } },
|
|
363
|
+
'2 years'],
|
|
364
|
+
[START_TIME,
|
|
365
|
+
START_TIME + 1.day + 2.hours + 30.minutes,
|
|
366
|
+
{ highest_measures: { max: 2, remainder: :round } },
|
|
367
|
+
'1 day and 3 hours'],
|
|
368
|
+
[START_TIME,
|
|
369
|
+
START_TIME + 1.day + 23.hours + 59.minutes + 59.seconds,
|
|
370
|
+
{ highest_measures: { max: 3, remainder: :round } },
|
|
371
|
+
'2 days'],
|
|
372
|
+
[START_TIME,
|
|
373
|
+
START_TIME + 1.day,
|
|
374
|
+
{ highest_measures: { remainder: :ceiling }, only: :months },
|
|
375
|
+
'less than 1 month'],
|
|
376
|
+
[START_TIME,
|
|
377
|
+
# Simplistic rounding: one would expect this to round up to a second week.
|
|
378
|
+
START_TIME + 1.week + 3.days + 23.hours,
|
|
379
|
+
{ highest_measures: { remainder: :round } },
|
|
380
|
+
'1 week'],
|
|
381
|
+
[START_TIME,
|
|
382
|
+
# Simplistic rounding: in some months, 15 days is less than half, but we always round it up.
|
|
383
|
+
START_TIME + 1.month + 14.days,
|
|
384
|
+
{ highest_measures: { remainder: :round } },
|
|
385
|
+
'2 months'],
|
|
316
386
|
].each do |start, finish, options, output|
|
|
317
387
|
it "should be #{output}" do
|
|
318
388
|
expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
|
|
319
389
|
end
|
|
320
390
|
end
|
|
321
391
|
|
|
392
|
+
it "raises ArgumentError when an unrecognized value is passed for highest_measure.remainder" do
|
|
393
|
+
expect do
|
|
394
|
+
distance_of_time_in_words(START_TIME, START_TIME + 1.day, true, { highest_measures: { remainder: :oops }})
|
|
395
|
+
end.to raise_error(ArgumentError)
|
|
396
|
+
end
|
|
397
|
+
|
|
322
398
|
if defined?(ActionView)
|
|
323
399
|
describe 'ActionView without include seconds argument' do
|
|
324
400
|
[
|
|
@@ -370,7 +446,7 @@ describe 'A better distance_of_time_in_words' do
|
|
|
370
446
|
expect(distance_of_time_in_words(start, finish, true, options)).to eq(output)
|
|
371
447
|
end
|
|
372
448
|
end
|
|
373
|
-
|
|
449
|
+
|
|
374
450
|
context 'via ActionController::Base.helpers' do
|
|
375
451
|
it '#distance_of_time_in_words' do
|
|
376
452
|
end_time = START_TIME + 1.year + 2.months + 3.weeks + 4.days + 5.hours + 6.minutes + 7.seconds
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
seconds:
|
|
2
|
+
1.second: སྐར་ཆ་ ༡
|
|
3
|
+
3.seconds: སྐར་ཆ་ 3
|
|
4
|
+
minutes:
|
|
5
|
+
1.minute: སྐར་མ་ ༡
|
|
6
|
+
20.minutes: སྐར་མ་ 20
|
|
7
|
+
hours:
|
|
8
|
+
1.hour: ཆུ་ཚོད་ ༡
|
|
9
|
+
5.hours: ཆུ་ཚོད་ 5
|
|
10
|
+
days:
|
|
11
|
+
1.day: ཉིནམ་ ༡
|
|
12
|
+
6.days: ཉིནམ་ 6
|
|
13
|
+
weeks:
|
|
14
|
+
1.week: བདུན༌ཕྲག་ ༡
|
|
15
|
+
2.weeks: བདུན༌ཕྲག་ 2
|
|
16
|
+
months:
|
|
17
|
+
1.month: ཟླཝ་ ༡
|
|
18
|
+
9.months: ཟླཝ་ 9
|
|
19
|
+
years:
|
|
20
|
+
1.year: ལོ་ ༡
|
|
21
|
+
3.years: ལོ་ 3
|
data/spec/lib/i18n/ru.yml
CHANGED
|
@@ -3,3 +3,21 @@ seconds:
|
|
|
3
3
|
1.second: 1 секунда
|
|
4
4
|
minutes:
|
|
5
5
|
1.minute: 1 минута
|
|
6
|
+
compact seconds:
|
|
7
|
+
1.second: 1с
|
|
8
|
+
11.seconds: 11с
|
|
9
|
+
21.seconds: 21с
|
|
10
|
+
compact minutes:
|
|
11
|
+
1.minute: 1м
|
|
12
|
+
11.minutes: 11м
|
|
13
|
+
21.minutes: 21м
|
|
14
|
+
compact hours:
|
|
15
|
+
1.hour: 1ч
|
|
16
|
+
11.hours: 11ч
|
|
17
|
+
21.hours: 21ч
|
|
18
|
+
compact days:
|
|
19
|
+
1.day: 1д
|
|
20
|
+
compact years:
|
|
21
|
+
1.year: 1г
|
|
22
|
+
11.years: 11г
|
|
23
|
+
21.years: 21г
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dotiw
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.
|
|
4
|
+
version: 5.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Bigg
|
|
8
8
|
- Lauran Jansen
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: activesupport
|
|
@@ -123,6 +122,48 @@ dependencies:
|
|
|
123
122
|
- - "~>"
|
|
124
123
|
- !ruby/object:Gem::Version
|
|
125
124
|
version: 1.2.7
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: mutex_m
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: base64
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: bigdecimal
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
126
167
|
description: |-
|
|
127
168
|
dotiw is a gem for Rails that overrides the
|
|
128
169
|
default distance_of_time_in_words and provides
|
|
@@ -141,6 +182,7 @@ files:
|
|
|
141
182
|
- ".rspec"
|
|
142
183
|
- Appraisals
|
|
143
184
|
- CHANGELOG.md
|
|
185
|
+
- CODEOWNERS
|
|
144
186
|
- CONTRIBUTING.md
|
|
145
187
|
- Gemfile
|
|
146
188
|
- MIT-LICENSE
|
|
@@ -149,16 +191,19 @@ files:
|
|
|
149
191
|
- benchmarks/time_hash_bench.rb
|
|
150
192
|
- dotiw.gemspec
|
|
151
193
|
- gemfiles/.bundle/config
|
|
152
|
-
- gemfiles/rails_4.gemfile
|
|
153
194
|
- gemfiles/rails_5.0.gemfile
|
|
154
195
|
- gemfiles/rails_5.1.gemfile
|
|
155
196
|
- gemfiles/rails_5.2.gemfile
|
|
156
197
|
- gemfiles/rails_6.0.gemfile
|
|
198
|
+
- gemfiles/rails_7.0.gemfile
|
|
199
|
+
- gemfiles/rails_7.1.gemfile
|
|
200
|
+
- gemfiles/rails_7.2.gemfile
|
|
157
201
|
- lib/dotiw.rb
|
|
158
202
|
- lib/dotiw/action_view/helpers/date_helper.rb
|
|
159
203
|
- lib/dotiw/locale/ar.yml
|
|
160
204
|
- lib/dotiw/locale/da.yml
|
|
161
205
|
- lib/dotiw/locale/de.yml
|
|
206
|
+
- lib/dotiw/locale/dz.yml
|
|
162
207
|
- lib/dotiw/locale/en.yml
|
|
163
208
|
- lib/dotiw/locale/es.yml
|
|
164
209
|
- lib/dotiw/locale/fr.yml
|
|
@@ -182,6 +227,7 @@ files:
|
|
|
182
227
|
- spec/lib/i18n/ar.yml
|
|
183
228
|
- spec/lib/i18n/da.yml
|
|
184
229
|
- spec/lib/i18n/de.yml
|
|
230
|
+
- spec/lib/i18n/dz.yml
|
|
185
231
|
- spec/lib/i18n/en.yml
|
|
186
232
|
- spec/lib/i18n/es.yml
|
|
187
233
|
- spec/lib/i18n/fr.yml
|
|
@@ -203,7 +249,6 @@ homepage: https://github.com/radar/distance_of_time_in_words
|
|
|
203
249
|
licenses:
|
|
204
250
|
- MIT
|
|
205
251
|
metadata: {}
|
|
206
|
-
post_install_message:
|
|
207
252
|
rdoc_options: []
|
|
208
253
|
require_paths:
|
|
209
254
|
- lib
|
|
@@ -218,8 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
218
263
|
- !ruby/object:Gem::Version
|
|
219
264
|
version: '0'
|
|
220
265
|
requirements: []
|
|
221
|
-
rubygems_version: 3.
|
|
222
|
-
signing_key:
|
|
266
|
+
rubygems_version: 3.6.9
|
|
223
267
|
specification_version: 4
|
|
224
268
|
summary: Better distance_of_time_in_words for Rails
|
|
225
269
|
test_files:
|
|
@@ -227,6 +271,7 @@ test_files:
|
|
|
227
271
|
- spec/lib/i18n/ar.yml
|
|
228
272
|
- spec/lib/i18n/da.yml
|
|
229
273
|
- spec/lib/i18n/de.yml
|
|
274
|
+
- spec/lib/i18n/dz.yml
|
|
230
275
|
- spec/lib/i18n/en.yml
|
|
231
276
|
- spec/lib/i18n/es.yml
|
|
232
277
|
- spec/lib/i18n/fr.yml
|