# HG changeset patch # User cmlenz # Date 1216126432 0 # Node ID 0ca28858045e01f5a9cd7b1e4147d2519bbe1a8a # Parent 250c7cba8c12c7acb105e5d6754740115321bcc2 Doc improvements for the new `format_timedelta` function. diff --git a/babel/core.py b/babel/core.py --- 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` """) diff --git a/babel/dates.py b/babel/dates.py --- 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 diff --git a/doc/dates.txt b/doc/dates.txt --- 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 =================