Skip to content
This repository
Browse code

Introduce :almost keyword for distance_of_time_in_words. Make 1.75 da…

…ys - 2 days return '2 days'.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#3266 state:committed]
  • Loading branch information...
commit c9318e9010712aeae33b1dd0e8bed4795ae37caf 1 parent 8ef1cd9
John Trupiano authored September 26, 2009 NZKoz committed September 28, 2009
29  actionpack/lib/action_view/helpers/date_helper.rb
@@ -26,8 +26,10 @@ module DateHelper
26 26
       #   47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs            # => [2..29] days
27 27
       #   29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs   # => about 1 month
28 28
       #   59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec                    # => [2..12] months
29  
-      #   1 yr <-> 2 yrs minus 1 secs                                               # => about 1 year
30  
-      #   2 yrs <-> max time or date                                                # => over [2..X] years
  29
+      #   1 yr <-> 1 yr, 3 months                                                   # => about 1 year
  30
+      #   1 yr, 3 months <-> 1 yr, 9 months                                         # => over 1 year
  31
+      #   1 yr, 9 months <-> 2 yr minus 1 sec                                       # => almost 2 years
  32
+      #   2 yrs <-> max time or date                                                # => (same rules as 1 yr)
31 33
       #
32 34
       # With <tt>include_seconds</tt> = true and the difference < 1 minute 29 seconds:
33 35
       #   0-4   secs      # => less than 5 seconds
@@ -53,8 +55,8 @@ module DateHelper
53 55
       #   distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years
54 56
       #
55 57
       #   to_time = Time.now + 6.years + 19.days
56  
-      #   distance_of_time_in_words(from_time, to_time, true)     # => over 6 years
57  
-      #   distance_of_time_in_words(to_time, from_time, true)     # => over 6 years
  58
+      #   distance_of_time_in_words(from_time, to_time, true)     # => about 6 years
  59
+      #   distance_of_time_in_words(to_time, from_time, true)     # => about 6 years
58 60
       #   distance_of_time_in_words(Time.now, Time.now)           # => less than a minute
59 61
       #
60 62
       def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, options = {})
@@ -82,14 +84,21 @@ def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false, o
82 84
             when 2..44           then locale.t :x_minutes,      :count => distance_in_minutes
83 85
             when 45..89          then locale.t :about_x_hours,  :count => 1
84 86
             when 90..1439        then locale.t :about_x_hours,  :count => (distance_in_minutes.to_f / 60.0).round
85  
-            when 1440..2879      then locale.t :x_days,         :count => 1
86  
-            when 2880..43199     then locale.t :x_days,         :count => (distance_in_minutes / 1440).round
  87
+            when 1440..2529      then locale.t :x_days,         :count => 1
  88
+            when 2530..43199     then locale.t :x_days,         :count => (distance_in_minutes.to_f / 1440.0).round
87 89
             when 43200..86399    then locale.t :about_x_months, :count => 1
88  
-            when 86400..525599   then locale.t :x_months,       :count => (distance_in_minutes / 43200).round
  90
+            when 86400..525599   then locale.t :x_months,       :count => (distance_in_minutes.to_f / 43200.0).round
89 91
             else
90  
-              return distance_in_minutes % 525600 < 262800 ?
91  
-                     locale.t(:about_x_years, :count => (distance_in_minutes / 525600).round) :
92  
-                     locale.t(:over_x_years, :count => (distance_in_minutes / 525600).round)
  92
+              distance_in_years           = distance_in_minutes / 525600
  93
+              minute_offset_for_leap_year = (distance_in_years / 4) * 1440
  94
+              remainder                   = ((distance_in_minutes - minute_offset_for_leap_year) % 525600)
  95
+              if remainder < 131400
  96
+                locale.t(:about_x_years,  :count => distance_in_years)
  97
+              elsif remainder < 394200
  98
+                locale.t(:over_x_years,   :count => distance_in_years)
  99
+              else
  100
+                locale.t(:almost_x_years, :count => distance_in_years + 1)
  101
+              end
93 102
           end
94 103
         end
95 104
       end
3  actionpack/lib/action_view/locale/en.yml
@@ -91,6 +91,9 @@
91 91
       over_x_years:
92 92
         one:   "over 1 year"
93 93
         other: "over {{count}} years"
  94
+      almost_x_years:
  95
+        one:   "almost 1 year"
  96
+        other: "almost {{count}} years"
94 97
     prompts:
95 98
       year:   "Year"
96 99
       month:  "Month"
19  actionpack/test/template/date_helper_i18n_test.rb
@@ -20,15 +20,16 @@ def test_distance_of_time_in_words_calls_i18n
20 20
       [60.seconds, true]  => [:'x_minutes',           1],
21 21
 
22 22
       # without include_seconds
23  
-      [29.seconds, false] => [:'less_than_x_minutes', 1],
24  
-      [60.seconds, false] => [:'x_minutes',           1],
25  
-      [44.minutes, false] => [:'x_minutes',           44],
26  
-      [61.minutes, false] => [:'about_x_hours',       1],
27  
-      [24.hours,   false] => [:'x_days',              1],
28  
-      [30.days,    false] => [:'about_x_months',      1],
29  
-      [60.days,    false] => [:'x_months',            2],
30  
-      [1.year,     false] => [:'about_x_years',       1],
31  
-      [3.years,    false] => [:'over_x_years',        3]
  23
+      [29.seconds,          false] => [:'less_than_x_minutes', 1],
  24
+      [60.seconds,          false] => [:'x_minutes',           1],
  25
+      [44.minutes,          false] => [:'x_minutes',           44],
  26
+      [61.minutes,          false] => [:'about_x_hours',       1],
  27
+      [24.hours,            false] => [:'x_days',              1],
  28
+      [30.days,             false] => [:'about_x_months',      1],
  29
+      [60.days,             false] => [:'x_months',            2],
  30
+      [1.year,              false] => [:'about_x_years',       1],
  31
+      [3.years + 6.months,  false] => [:'over_x_years',        3],
  32
+      [3.years + 10.months, false] => [:'almost_x_years',      4]
32 33
 
33 34
       }.each do |passed, expected|
34 35
       assert_distance_of_time_in_words_translates_key passed, expected
39  actionpack/test/template/date_helper_test.rb
@@ -53,13 +53,14 @@ def assert_distance_of_time_in_words(from, to=nil)
53 53
     assert_equal "about 2 hours", distance_of_time_in_words(from, to + 89.minutes + 30.seconds)
54 54
     assert_equal "about 24 hours", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 29.seconds)
55 55
 
56  
-    # 1440..2879
  56
+    # 1440..2529
57 57
     assert_equal "1 day", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 30.seconds)
58  
-    assert_equal "1 day", distance_of_time_in_words(from, to + 47.hours + 59.minutes + 29.seconds)
  58
+    assert_equal "1 day", distance_of_time_in_words(from, to + 41.hours + 59.minutes + 29.seconds)
59 59
 
60  
-    # 2880..43199
61  
-    assert_equal "2 days", distance_of_time_in_words(from, to + 47.hours + 59.minutes + 30.seconds)
62  
-    assert_equal "29 days", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 29.seconds)
  60
+    # 2530..43199
  61
+    assert_equal "2 days", distance_of_time_in_words(from, to + 42.hours + 59.minutes + 30.seconds)
  62
+    assert_equal "3 days", distance_of_time_in_words(from, to + 2.days + 12.hours)
  63
+    assert_equal "30 days", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 29.seconds)
63 64
 
64 65
     # 43200..86399
65 66
     assert_equal "about 1 month", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 30.seconds)
@@ -70,13 +71,27 @@ def assert_distance_of_time_in_words(from, to=nil)
70 71
     assert_equal "12 months", distance_of_time_in_words(from, to + 1.years - 31.seconds)
71 72
 
72 73
     # > 525599
73  
-    assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years - 30.seconds)
74  
-    assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years + 6.months - 1.day)
75  
-    assert_equal "over 1 year", distance_of_time_in_words(from, to + 1.years + 6.months)
76  
-    assert_equal "about 2 years", distance_of_time_in_words(from, to + 2.years + 30.seconds)
77  
-    assert_equal "about 5 years", distance_of_time_in_words(from, to + 5.years + 5.months)
78  
-    assert_equal "over 5 years", distance_of_time_in_words(from, to + 5.years + 6.months)
79  
-    assert_equal "about 10 years", distance_of_time_in_words(from, to + 10.years)
  74
+    assert_equal "about 1 year",    distance_of_time_in_words(from, to + 1.years - 30.seconds)
  75
+    assert_equal "about 1 year",    distance_of_time_in_words(from, to + 1.years + 3.months - 1.day)
  76
+    assert_equal "over 1 year",     distance_of_time_in_words(from, to + 1.years + 6.months)
  77
+
  78
+    assert_equal "almost 2 years",  distance_of_time_in_words(from, to + 2.years - 3.months + 1.day)
  79
+    assert_equal "about 2 years",   distance_of_time_in_words(from, to + 2.years + 3.months - 1.day)
  80
+    assert_equal "over 2 years",    distance_of_time_in_words(from, to + 2.years + 3.months + 1.day)
  81
+    assert_equal "over 2 years",    distance_of_time_in_words(from, to + 2.years + 9.months - 1.day)
  82
+    assert_equal "almost 3 years",  distance_of_time_in_words(from, to + 2.years + 9.months + 1.day)
  83
+
  84
+    assert_equal "almost 5 years",  distance_of_time_in_words(from, to + 5.years - 3.months + 1.day)
  85
+    assert_equal "about 5 years",   distance_of_time_in_words(from, to + 5.years + 3.months - 1.day)
  86
+    assert_equal "over 5 years",    distance_of_time_in_words(from, to + 5.years + 3.months + 1.day)
  87
+    assert_equal "over 5 years",    distance_of_time_in_words(from, to + 5.years + 9.months - 1.day)
  88
+    assert_equal "almost 6 years",  distance_of_time_in_words(from, to + 5.years + 9.months + 1.day)
  89
+
  90
+    assert_equal "almost 10 years", distance_of_time_in_words(from, to + 10.years - 3.months + 1.day)
  91
+    assert_equal "about 10 years",  distance_of_time_in_words(from, to + 10.years + 3.months - 1.day)
  92
+    assert_equal "over 10 years",   distance_of_time_in_words(from, to + 10.years + 3.months + 1.day)
  93
+    assert_equal "over 10 years",   distance_of_time_in_words(from, to + 10.years + 9.months - 1.day)
  94
+    assert_equal "almost 11 years", distance_of_time_in_words(from, to + 10.years + 9.months + 1.day)
80 95
 
81 96
     # test to < from
82 97
     assert_equal "about 4 hours", distance_of_time_in_words(from + 4.hours, to)

0 notes on commit c9318e9

Please sign in to comment.
Something went wrong with that request. Please try again.