Ticket #12194: natural_timedelta.diff
File natural_timedelta.diff, 8.0 KB (added by , 15 years ago) |
---|
-
django/contrib/humanize/templatetags/humanize.py
2 2 from django.utils.encoding import force_unicode 3 3 from django import template 4 4 from django.template import defaultfilters 5 from datetime import date5 import datetime 6 6 import re 7 7 8 8 register = template.Library() … … 81 81 formatted according to settings.DATE_FORMAT. 82 82 """ 83 83 try: 84 value = date (value.year, value.month, value.day)84 value = datetime.date(value.year, value.month, value.day) 85 85 except AttributeError: 86 86 # Passed value wasn't a date object 87 87 return value 88 88 except ValueError: 89 89 # Date arguments out of range 90 90 return value 91 delta = value - date .today()91 delta = value - datetime.date.today() 92 92 if delta.days == 0: 93 93 return _(u'today') 94 94 elif delta.days == 1: … … 97 97 return _(u'yesterday') 98 98 return defaultfilters.date(value, arg) 99 99 register.filter(naturalday) 100 101 def natural_timedelta(time1, time2=datetime.datetime.now()): 102 """ 103 Express the difference in time between time1 and time2 (which defaults to 104 now) in a human-friendly way (e.g. 'about 1 minute'). 105 """ 106 try: 107 delta = abs(time1 - time2) 108 delta.days 109 except (ValueError, AttributeError, TypeError): 110 return time1 111 if delta.days == 0: 112 delta_days = 0 113 delta_minutes = int(round(delta.seconds / 60.0)) 114 if delta.seconds in range(0, 50): 115 if delta.seconds in range(0, 5): 116 return _(u'less than %(count)d seconds') % {'count': 5} 117 elif delta.seconds in range(5, 10): 118 return _(u'less than %(count)d seconds') % {'count': 10} 119 elif delta.seconds in range(10, 20): 120 return _(u'less than %(count)d seconds') % {'count': 20} 121 elif delta.seconds in range(20, 40): 122 return _(u'about half a minute') 123 elif delta.seconds in range(40, 50): 124 return _(u'less than a minute') 125 elif delta_minutes in range(1, 45): 126 return ungettext(u'about %(count)d minute', u'about %(count)d minutes', delta_minutes) % {'count': delta_minutes} 127 elif delta_minutes in range(45, 90): 128 return _(u'about %(count)d hour') % {'count': 1} 129 elif delta_minutes in range(90, 1440): 130 return _(u'about %(count)d hours') % {'count': round(delta_minutes / 60.0)} 131 else: 132 delta_days = int(round(delta.days + (delta.seconds / 86400.0))) 133 if delta_days in range(1, 30): 134 return ungettext(u'about %(count)d day', u'about %(count)d days', delta_days) % {'count': delta_days} 135 elif delta_days in range(30, 365): 136 count = round(delta_days / 30.4) 137 return ungettext(u'about %(count)d month', u'about %(count)d months', count) % {'count': count} 138 elif delta_days >= 365: 139 count = round(delta_days / 365.25) 140 return ungettext(u'about %(count)d year', u'about %(count)d years', count) % {'count': count} 141 register.filter(natural_timedelta) -
tests/regressiontests/humanize/tests.py
1 1 import unittest 2 from datetime import timedelta, date2 import datetime 3 3 from django.template import Template, Context, add_to_builtins 4 4 from django.utils.dateformat import DateFormat 5 5 from django.utils.translation import ugettext as _ … … 54 54 55 55 def test_naturalday(self): 56 56 from django.template import defaultfilters 57 today = date .today()58 yesterday = today - timedelta(days=1)59 tomorrow = today + timedelta(days=1)60 someday = today - timedelta(days=10)57 today = datetime.date.today() 58 yesterday = today - datetime.timedelta(days=1) 59 tomorrow = today + datetime.timedelta(days=1) 60 someday = today - datetime.timedelta(days=10) 61 61 notdate = u"I'm not a date value" 62 62 63 63 test_list = (today, yesterday, tomorrow, someday, notdate) … … 65 65 result_list = (_(u'today'), _(u'yesterday'), _(u'tomorrow'), 66 66 someday_result, u"I'm not a date value") 67 67 self.humanize_tester(test_list, result_list, 'naturalday') 68 69 def test_natural_timedelta(self): 70 now = datetime.datetime.now() 71 72 test_list = ( 73 now, 74 now + datetime.timedelta(microseconds=4), 75 now + datetime.timedelta(seconds=4), 76 now + datetime.timedelta(seconds=9), 77 now + datetime.timedelta(seconds=19), 78 now + datetime.timedelta(seconds=31), 79 now + datetime.timedelta(seconds=45), 80 now + datetime.timedelta(seconds=55), 81 now + datetime.timedelta(seconds=60), 82 now + datetime.timedelta(seconds=121), 83 now + datetime.timedelta(seconds=400), 84 now + datetime.timedelta(seconds=2700), 85 now + datetime.timedelta(seconds=3660), 86 now + datetime.timedelta(seconds=11880), 87 now + datetime.timedelta(seconds=82800), 88 now + datetime.timedelta(days=1), 89 now + datetime.timedelta(days=1.5), 90 now + datetime.timedelta(days=29), 91 now + datetime.timedelta(days=30), 92 now + datetime.timedelta(days=60), 93 now + datetime.timedelta(days=340), 94 now + datetime.timedelta(days=365), 95 now + datetime.timedelta(days=730.5), 96 now + datetime.timedelta(days=2922), 97 now - datetime.timedelta(seconds=45), 98 u'spam', 99 1, 100 ) 101 result_list = ( 102 _(u'less than 5 seconds'), 103 _(u'less than 5 seconds'), 104 _(u'less than 5 seconds'), 105 _(u'less than 10 seconds'), 106 _(u'less than 20 seconds'), 107 _(u'about half a minute'), 108 _(u'less than a minute'), 109 _(u'about 1 minute'), 110 _(u'about 1 minute'), 111 _(u'about 2 minutes'), 112 _(u'about 7 minutes'), 113 _(u'about 1 hour'), 114 _(u'about 1 hour'), 115 _(u'about 3 hours'), 116 _(u'about 23 hours'), 117 _(u'about 1 day'), 118 _(u'about 2 days'), 119 _(u'about 29 days'), 120 _(u'about 1 month'), 121 _(u'about 2 months'), 122 _(u'about 11 months'), 123 _(u'about 1 year'), 124 _(u'about 2 years'), 125 _(u'about 8 years'), 126 _(u'less than a minute'), 127 u'spam', 128 1, 129 ) 130 self.humanize_tester(test_list, result_list, 'natural_timedelta') 68 131 69 132 if __name__ == '__main__': 70 133 unittest.main() -
docs/ref/contrib/humanize.txt
89 89 * ``18 Feb 2007`` becomes ``tomorrow``. 90 90 * Any other day is formatted according to given argument or the 91 91 :setting:`DATE_FORMAT` setting if no argument is given. 92 93 natural_timedelta 94 ----------------- 95 96 .. versionadded:: 1.2 97 98 Determine the difference between one date and/or time object and another and 99 return that difference in a human-friendly format. 100 101 **Argument:** A date and/or time object (i.e. ``datetime.date``, 102 ``datetime.time`` or ``datetime.datetime``). Defaults to 103 ``datetime.datetime.now()`` if not given. 104 105 Examples: 106 107 * A difference of 9 seconds becomes ``less than 10 seconds``. 108 * A difference of 30 seconds becomes ``about half a minute``. 109 * A difference of 1 minute, 10 seconds becomes ``about 1 minute``. 110 * A difference of 30 days becomes ``about 1 month``. 111 * A difference of 365 days becomes ``about 1 year``.