123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- # Copyright (c) Django Software Foundation and individual contributors.
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without modification,
- # are permitted provided that the following conditions are met:
- #
- # 1. Redistributions of source code must retain the above copyright notice,
- # this list of conditions and the following disclaimer.
- #
- # 2. Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- #
- # 3. Neither the name of Django nor the names of its contributors may be used
- # to endorse or promote products derived from this software without
- # specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- from __future__ import unicode_literals
- import datetime
- import pytz
- from mediagoblin.tools.translate import pass_to_ugettext, lazy_pass_to_ungettext as _
- def timesince(d, now=None, reversed=False):
- """
- Takes two datetime objects and returns the time between d and now
- as a nicely formatted string, e.g. "10 minutes". If d occurs after now,
- then "0 minutes" is returned.
- Units used are years, months, weeks, days, hours, and minutes.
- Seconds and microseconds are ignored. Up to two adjacent units will be
- displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are
- possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
- Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
- """
- chunks = (
- (60 * 60 * 24 * 365, lambda n: _('year', 'years', n)),
- (60 * 60 * 24 * 30, lambda n: _('month', 'months', n)),
- (60 * 60 * 24 * 7, lambda n : _('week', 'weeks', n)),
- (60 * 60 * 24, lambda n : _('day', 'days', n)),
- (60 * 60, lambda n: _('hour', 'hours', n)),
- (60, lambda n: _('minute', 'minutes', n))
- )
- # Convert datetime.date to datetime.datetime for comparison.
- if not isinstance(d, datetime.datetime):
- d = datetime.datetime(d.year, d.month, d.day)
- if now and not isinstance(now, datetime.datetime):
- now = datetime.datetime(now.year, now.month, now.day)
- if not now:
- now = datetime.datetime.utcnow()
- delta = (d - now) if reversed else (now - d)
- # ignore microseconds
- since = delta.days * 24 * 60 * 60 + delta.seconds
- if since <= 0:
- # d is in the future compared to now, stop processing.
- return '0 ' + pass_to_ugettext('minutes')
- for i, (seconds, name) in enumerate(chunks):
- count = since // seconds
- if count != 0:
- break
- s = pass_to_ugettext('%(number)d %(type)s') % {'number': count, 'type': name(count)}
- if i + 1 < len(chunks):
- # Now get the second item
- seconds2, name2 = chunks[i + 1]
- count2 = (since - (seconds * count)) // seconds2
- if count2 != 0:
- s += pass_to_ugettext(', %(number)d %(type)s') % {'number': count2, 'type': name2(count2)}
- return s
|