changeset 396:45a5b2266001

Doc improvements for the new `format_timedelta` function.
author cmlenz
date Tue, 15 Jul 2008 12:53:52 +0000
parents 98f06b9c44a7
children ff9a6a37eb72
files babel/core.py babel/dates.py doc/dates.txt
diffstat 3 files changed, 84 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/babel/core.py
+++ b/babel/core.py
@@ -612,6 +612,8 @@
         'other'
         >>> Locale('fr').plural_form(0)
         'one'
+        >>> Locale('ru').plural_form(100)
+        'many'
         
         :type: `PluralRule`
         """)
--- a/babel/dates.py
+++ b/babel/dates.py
@@ -21,13 +21,14 @@
  * ``LANG``
 """
 
+from __future__ import division
 from datetime import date, datetime, time, timedelta, tzinfo
 import re
 
 from babel.core import default_locale, get_global, Locale
 from babel.util import UTC
 
-__all__ = ['format_date', 'format_datetime', 'format_time',
+__all__ = ['format_date', 'format_datetime', 'format_time', 'format_timedelta',
            'get_timezone_name', 'parse_date', 'parse_datetime', 'parse_time']
 __docformat__ = 'restructuredtext en'
 
@@ -599,31 +600,55 @@
     ('second', 1)
 )
 
-def format_timedelta(delta, granularity='second', threshold=.9, locale=LC_TIME):
+def format_timedelta(delta, granularity='second', threshold=.85, locale=LC_TIME):
     """Return a time delta according to the rules of the given locale.
-    
+
     >>> format_timedelta(timedelta(weeks=12), locale='en_US')
     u'3 months'
     >>> format_timedelta(timedelta(seconds=1), locale='es')
     u'1 segundo'
-    >>> format_timedelta(timedelta(seconds=1), locale='en_US')
-    u'1 second'
+
+    The granularity parameter can be provided to alter the lowest unit
+    presented, which defaults to a second.
     
+    >>> format_timedelta(timedelta(hours=3), granularity='day',
+    ...                  locale='en_US')
+    u'0 days'
+
+    The threshold parameter can be used to determine at which value the
+    presentation switches to the next higher unit. A higher threshold factor
+    means the presentation will switch later. For example:
+
+    >>> format_timedelta(timedelta(hours=23), threshold=0.9, locale='en_US')
+    u'1 day'
+    >>> format_timedelta(timedelta(hours=23), threshold=1.1, locale='en_US')
+    u'23 hours'
+
     :param delta: a ``timedelta`` object representing the time difference to
-                  format
-    
+                  format, or the delta in seconds as an `int` value
+    :param granularity: determines the smallest unit that should be displayed,
+                        the value can be one of "year", "month", "week", "day",
+                        "hour", "minute" or "second"
+    :param threshold: factor that determines at which point the presentation
+                      switches to the next higher unit
+    :param locale: a `Locale` object or a locale identifier
+    :rtype: `unicode`
     """
+    if isinstance(delta, timedelta):
+        seconds = int((delta.days * 86400) + delta.seconds)
+    else:
+        seconds = delta
     locale = Locale.parse(locale)
-    seconds = int((delta.days * 86400) + delta.seconds)
 
-    for unit, limit in TIMEDELTA_UNITS:
-        r = float(abs(seconds)) / float(limit)
-        if r >= threshold or unit == granularity:
-            r = int(round(r))
-            plural_form = locale.plural_form(r)
+    for unit, secs_per_unit in TIMEDELTA_UNITS:
+        value = abs(seconds) / secs_per_unit
+        if value >= threshold or unit == granularity:
+            value = int(round(value))
+            plural_form = locale.plural_form(value)
             pattern = locale._data['unit_patterns'][unit][plural_form]
-            return pattern.replace('{0}', str(r))
-    return ''
+            return pattern.replace('{0}', str(value))
+
+    return u''
 
 def parse_date(string, locale=LC_TIME):
     """Parse a date from a string.
@@ -853,7 +878,7 @@
         return self.format(self.get_day_of_year(), num)
 
     def format_day_of_week_in_month(self):
-        return '%d' % ((self.value.day - 1) / 7 + 1)
+        return '%d' % ((self.value.day - 1) // 7 + 1)
 
     def format_period(self, char):
         period = {0: 'am', 1: 'pm'}[int(self.value.hour >= 12)]
@@ -918,7 +943,7 @@
                      day_of_period + 1) % 7
         if first_day < 0:
             first_day += 7
-        week_number = (day_of_period + first_day - 1) / 7
+        week_number = (day_of_period + first_day - 1) // 7
         if 7 - first_day >= self.locale.min_week_days:
             week_number += 1
         return week_number
--- a/doc/dates.txt
+++ b/doc/dates.txt
@@ -197,6 +197,46 @@
   +----------+--------+--------------------------------------------------------+
 
 
+Time Delta Formatting
+=====================
+
+In addition to providing functions for formatting localized dates and times,
+the ``babel.dates`` module also provides a function to format the difference
+between two times, called a ''time delta''. These are usually represented as
+``datetime.timedelta`` objects in Python, and it's also what you get when you
+subtract one ``datetime`` object from an other.
+
+The ``format_timedelta`` function takes a ``timedelta`` object and returns a
+human-readable representation. This happens at the cost of precision, as it
+chooses only the most significant unit (such as year, week, or hour) of the
+difference, and displays that:
+
+.. code-block:: pycon
+
+    >>> from datetime import timedelta
+    >>> from babel.dates import format_timedelta
+    >>> delta = timedelta(days=6)
+    >>> format_timedelta(delta, locale='en_US')
+    u'1 week'
+
+The resulting strings are based from the CLDR data, and are properly
+pluralized depending on the plural rules of the locale and the calculated
+number of units.
+
+The function provides parameters for you to influence how this most significant
+unit is chosen: with ``threshold`` you set the value after which the
+presentation switches to the next larger unit, and with ``granularity`` you
+can limit the smallest unit to display:
+
+.. code-block:: pycon
+
+    >>> delta = timedelta(days=6)
+    >>> format_timedelta(delta, threshold=1.2, locale='en_US')
+    u'6 days'
+    >>> format_timedelta(delta, granularity='month', locale='en_US')
+    u'0 months'
+
+
 Time-zone Support
 =================
 
Copyright (C) 2012-2017 Edgewall Software