Commits

Anonymous committed b8fa3c0

[svn] more precise distance_of_time_in_seconds

  • Participants
  • Parent commits a0502dc

Comments (0)

Files changed (3)

 WebHelpers ChangeLog
 
 0.2.1 (**svn**)
+* More precise distance_of_time_in_words (Follows bottom half of #4989 Rails
+  changeset)
 * button_to accepts method keyword so you can PUT and DELETE with it. 
   (Follows #4914 Rails changeset)
 * Fixed auto_link to parse more valid url formats (Thanks Jamie Wilkinson).

tests/test_date.py

         self.assertEqual("about 1 hour", distance_of_time_in_words(60*60, 0))
         
         # additional tests
-        # exactly 24 hrs should be about 24 hrs - to be the same as Rails (it should be 1 day)
-        self.assertEqual("about 24 hours", distance_of_time_in_words(from_time, datetime(2004, 3, 7, 21, 41, 18)))
+        # exactly 24 hrs
         self.assertEqual("1 day", distance_of_time_in_words(from_time, datetime(2004, 3, 7, 21, 51, 18)))
         # test > 30, but < 60 s, i.e. closer to a minute if rounded
         self.assertEqual("1 minute", distance_of_time_in_words(from_time, datetime(2004, 3, 6, 21, 41, 50)))
         self.assertEqual("about 3 hours", distance_of_time_in_words(11160))
         self.assertEqual("about 4 hours", distance_of_time_in_words(14399))
         self.assertEqual("2 days", distance_of_time_in_words(180000))
-        # exactly 24 hrs should be about 24 hrs - to be the same as Rails (it should be 1 day)
-        self.assertEqual("about 24 hours", distance_of_time_in_words(86400))
+        # exactly 24 hrs
+        self.assertEqual("1 day", distance_of_time_in_words(86400))
         self.assertEqual("1 day", distance_of_time_in_words(87000))
 
     def test_time_ago_in_words(self):
 if __name__ == '__main__':
     suite = [unittest.makeSuite(TestDateHelper)]
     for testsuite in suite:
-        unittest.TextTestRunner(verbosity=1).run(testsuite)
+        unittest.TextTestRunner(verbosity=1).run(testsuite)

webhelpers/rails/date.py

 """Date/Time Helpers"""
-# Last synced with Rails copy at Revision 4674 on Aug 19th, 2006.
+# Last synced with Rails copy at Revision 4989 on Sep 4th, 2006.
 # Note that the select_ tags are purposely not ported as they're very totally useless
 # and inefficient beyond comprehension.
 
 
 def distance_of_time_in_words(from_time, to_time=0, include_seconds=False):
     """
-    Reports the approximate distance in time between two datetime objects or integers. 
-    
-    For example, if the distance is 47 minutes, it'll return
-    "about 1 hour". See the source for the complete wording list.
-    
-    Integers are interpreted as seconds from now. So,
-    ``distance_of_time_in_words(50)`` returns "less than a minute".
-    
-    Set ``include_seconds`` to True if you want more detailed approximations if distance < 1 minute
+    Reports the approximate distance in time between two datetime objects or
+    integers as seconds.
+
+    Set ``include_seconds`` to True for more more detailed approximations when
+    distance < 1 min, 29 secs
+
+    Distances are reported based on the following table:
+
+    0 <-> 29 secs                                                           => less than a minute
+    30 secs <-> 1 min, 29 secs                                              => 1 minute
+    1 min, 30 secs <-> 44 mins, 29 secs                                     => [2..44] minutes
+    44 mins, 30 secs <-> 89 mins, 29 secs                                   => about 1 hour
+    89 mins, 29 secs <-> 23 hrs, 59 mins, 29 secs                           => about [2..24] hours
+    23 hrs, 59 mins, 29 secs <-> 47 hrs, 59 mins, 29 secs                   => 1 day
+    47 hrs, 59 mins, 29 secs <-> 29 days, 23 hrs, 59 mins, 29 secs          => [2..29] days
+    29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs => about 1 month
+    59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 31 secs                => [2..12] months
+    1 yr minus 30 secs <-> 2 yrs minus 31 secs                              => about 1 year
+    2 yrs minus 30 secs <-> max time or date                                => over [2..X] years
+
+    With ``include_seconds`` set to True and the difference < 1 minute 29
+    seconds:
+
+    0-4   secs    => less than 5 seconds
+    5-9   secs    => less than 10 seconds
+    10-19 secs    => less than 20 seconds
+    20-39 secs    => half a minute
+    40-59 secs    => less than a minute
+    60-89 secs    => 1 minute
+
+    Examples:
+
+        >>> from_time = datetime.now()
+        >>> distance_of_time_in_words(from_time, from_time + timedelta(minutes=50))
+        'about 1 hour'
+        >>> distance_of_time_in_words(from_time, from_time + timedelta(seconds=15))
+        'less than a minute'
+        >>> distance_of_time_in_words(from_time, from_time + timedelta(seconds=15), include_seconds=True)
+        'less than 20 seconds'
+
+    Note: ``distance_of_time_in_words`` calculates one year as 365.25 days.
     """
     if isinstance(from_time, int):
         from_time = time.time()+from_time
                 return "less than a minute"
             else:
                 return "1 minute"
-    elif distance_in_minutes <= 45:
+    elif distance_in_minutes < 45:
         return "%s minutes" % distance_in_minutes
-    elif distance_in_minutes <= 90:
+    elif distance_in_minutes < 90:
         return "about 1 hour"
-    elif distance_in_minutes <= 1440:
+    elif distance_in_minutes < 1440:
         return "about %d hours" % (round(distance_in_minutes / 60.0))
-    elif distance_in_minutes <= 2880:
+    elif distance_in_minutes < 2880:
         return "1 day"
-    elif distance_in_minutes <= 43220:
+    elif distance_in_minutes < 43220:
         return "%d days" % (round(distance_in_minutes / 1440))
-    elif distance_in_minutes <= 86400:
+    elif distance_in_minutes < 86400:
         return "about 1 month"
-    elif distance_in_minutes <= 525960:
+    elif distance_in_minutes < 525960:
         return "%d months" % (round(distance_in_minutes / 43200))
-    elif distance_in_minutes <= 1051920:
+    elif distance_in_minutes < 1051920:
         return "about 1 year"
     else:
-        return "over %d years" % (round(distance_in_minutes / 525600))
+        return "over %d years" % (round(distance_in_minutes / 525960))
 
 def time_ago_in_words(from_time, include_seconds=False):
     """