Changeset 90

Show
Ignore:
Timestamp:
10/25/07 16:41:38 (15 months ago)
Author:
steadicat
Message:

Added rough human date formatting.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • django/trunk/contrib/humanise/templatetags/humanise.py

    r84 r90  
    1 import datetime 
     1if __name__=='__main__': 
     2    import sys, os 
     3    os.chdir('../../..') 
     4    sys.path.append('unicoders-contrib') 
     5 
     6from datetime import datetime, date 
     7from dateutil.relativedelta import relativedelta as delta 
    28 
    39from django import template 
     
    1824        # Date is in the future; return formatted date. 
    1925        return value.strftime("%B %d, %Y") 
     26 
     27class HumanDelta(object): 
     28 
     29    fields = ['year', 'month', 'week', 'day'] 
     30 
     31    def __init__(self, delta, simplify=True): 
     32        self.year = delta.years 
     33        self.month = delta.months 
     34        if delta.days >= 0: 
     35            self.week, self.day = divmod(delta.days, 7) 
     36        else: 
     37            self.week, self.day = divmod(-delta.days, 7) 
     38            self.week = -self.week 
     39            self.day = -self.day 
     40 
     41        self.format = '%s' 
     42        for field in self.fields: 
     43            if getattr(self, field) is not 0: 
     44                if getattr(self, field) > 0: 
     45                    self.format = 'in %s' 
     46                else: 
     47                    self.format = '%s ago' 
     48                    setattr(self, field, -getattr(self, field)) 
     49 
     50        if simplify: 
     51            self.simplify('day', 'week', 7) 
     52            self.simplify('week', 'month', 4.4) 
     53            self.simplify('month', 'year', 12) 
     54 
     55    def simplify(self, fro, to, factor): 
     56        ton = getattr(self, to) 
     57        if ton > 0: 
     58            diff = round(getattr(self, fro)*1.0/factor) 
     59            setattr(self, to, ton+diff) 
     60            setattr(self, fro, 0) 
     61 
     62    def field(self, name): 
     63        n = getattr(self, name) 
     64        if n == 0: 
     65            return None 
     66        elif n == 1: 
     67            return '1 %s' % name 
     68        else: 
     69            return '%d %ss' % (n, name) 
     70 
     71    def __str__(self): 
     72        fields = [self.field(f) for f in self.fields] 
     73        while None in fields: fields.remove(None) 
     74        if not fields: return 'today' 
     75        return self.format % ', '.join(fields[:-2] + [' and '.join(fields[-2:])]) 
     76 
     77@register.filter 
     78def humandate(value): 
     79    """ 
     80    Returns number of days between today and value. 
     81 
     82    >>> from datetime import date 
     83    >>> from dateutil.relativedelta import relativedelta as delta 
     84    >>> today = date.today() 
     85 
     86 
     87    >>> humandate( today ) 
     88    'today' 
     89 
     90    >>> humandate( today + delta(years=+1) ) 
     91    'in 1 year' 
     92 
     93    Year-month crossover. 
     94 
     95    >>> humandate( today + delta(months=+12) ) 
     96    'in 1 year' 
     97    >>> humandate( today + delta(months=+11) ) 
     98    'in 11 months' 
     99 
     100    Month-month crossover. 
     101 
     102    >>> humandate( today + delta( months=+6, days=+16 )) 
     103    'in 7 months' 
     104    >>> humandate( today + delta( months=+6, days=+15 )) 
     105    'in 6 months' 
     106    >>> humandate( today + delta( months=+6 )) 
     107    'in 6 months' 
     108    >>> humandate( today + delta( months=+6, days=-15 )) 
     109    'in 6 months' 
     110    >>> humandate( today + delta( months=+6, days=-16 )) 
     111    'in 5 months' 
     112 
     113    Month-week crossover. 
     114 
     115    >>> humandate( today + delta(days=31) ) 
     116    'in 1 month' 
     117    >>> humandate( today + delta(days=30) ) 
     118    'in 1 month' 
     119    >>> humandate( today + delta(days=29) ) 
     120    'in 4 weeks' 
     121    >>> humandate( today + delta(days=28) ) 
     122    'in 4 weeks' 
     123 
     124    Week-week crossover. 
     125 
     126    >>> humandate( today + delta(days=7+4) ) 
     127    'in 2 weeks' 
     128    >>> humandate( today + delta(days=7+3) ) 
     129    'in 1 week' 
     130 
     131    Week-day crossover. 
     132 
     133    >>> humandate( today + delta(days=7) ) 
     134    'in 1 week' 
     135    >>> humandate( today + delta(days=6) ) 
     136    'in 6 days' 
     137 
     138    Day-day-tomorrow crossover. 
     139 
     140    >>> humandate( today + delta(days=3) ) 
     141    'in 3 days' 
     142    >>> humandate( today + delta(days=2) ) 
     143    'in 2 days' 
     144    >>> humandate( today + delta(days=1) ) 
     145    'tomorrow' 
     146 
     147    >>> humandate( today - delta(days=2) ) 
     148    '2 days ago' 
     149 
     150    """ 
     151    if not value: return 'None' 
     152    today = date.today() 
     153    return str(HumanDelta(delta(value, today))) 
     154 
     155@register.filter 
     156def humanfulldate(value): 
     157    if not value: return 'None' 
     158    today = date.today() 
     159    return str(HumanDelta(delta(value, today), simplify=False)) 
     160 
     161if __name__=='__main__': 
     162    import doctest 
     163    doctest.testmod() 
     164