def naturaltime(value, future=False, months=True): """Given a datetime or a number of seconds, return a natural representation of that time in a resolution that makes sense. This is more or less compatible with Django's ``naturaltime`` filter. ``future`` is ignored for datetimes, where the tense is always figured out based on the current time. If an integer is passed, the return value will be past tense by default, unless ``future`` is set to True.""" now = _now() # dmc note: naturaltime is just relative, so we assume we're dealing with # UTC if now.tzinfo != value.tzinfo: raise ValueError("mismatched tzinfo") date, delta = date_and_delta(value) if date is None: return value # determine tense by value only if datetime/timedelta were passed if isinstance(value, (datetime.datetime, datetime.timedelta)): future = date > now ago = _('%s from now') if future else _('%s ago') delta = naturaldelta(delta) if delta == _("a moment"): return _("now") return ago % delta
def naturalday(value, format='%b %d', tz=None, local=None): """For date values that are tomorrow, today or yesterday compared to present day returns representing string. Otherwise, returns a string formatted according to ``format``.""" try: value = datetime.date(value.year, value.month, value.day) except AttributeError: # Passed value wasn't date-ish return value except (OverflowError, ValueError): # Date arguments out of range return value delta = value - _today(tz=tz, local=local) if delta.days == 0: return _('today') elif delta.days == 1: return _('tomorrow') elif delta.days == -1: return _('yesterday') return value.strftime(format)
def naturaldelta(value, months=True): """Given a timedelta or a number of seconds, return a natural representation of the amount of time elapsed. This is similar to ``naturaltime``, but does not add tense to the result. If ``months`` is True, then a number of months (based on 30.5 days) will be used for fuzziness between years.""" date, delta = date_and_delta(value) if date is None: return value use_months = months seconds = abs(delta.seconds) days = abs(delta.days) years = days // 365 days = days % 365 months = int(days // 30.5) if not years and days < 1: if seconds == 0: return _("a moment") elif seconds == 1: return _("a second") elif seconds < 60: return ngettext("%d second", "%d seconds", seconds) % seconds elif 60 <= seconds < 120: return _("a minute") elif 120 <= seconds < 3600: minutes = seconds // 60 return ngettext("%d minute", "%d minutes", minutes) % minutes elif 3600 <= seconds < 3600 * 2: return _("an hour") elif 3600 < seconds: hours = seconds // 3600 return ngettext("%d hour", "%d hours", hours) % hours elif years == 0: if days == 1: return _("a day") if not use_months: return ngettext("%d day", "%d days", days) % days else: if not months: return ngettext("%d day", "%d days", days) % days elif months == 1: return _("a month") else: return ngettext("%d month", "%d months", months) % months elif years == 1: if not months and not days: return _("a year") elif not months: return ngettext("1 year, %d day", "1 year, %d days", days) % days elif use_months: if months == 1: return _("1 year, 1 month") else: return ngettext("1 year, %d month", "1 year, %d months", months) % months else: return ngettext("1 year, %d day", "1 year, %d days", days) % days else: return ngettext("%d year", "%d years", years) % years