2014-07-22 21:47:01 +00:00
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
from django.utils import timezone
|
|
|
|
from django.utils.translation import ungettext, ugettext as _
|
|
|
|
|
|
|
|
|
|
|
|
def pluralize_year(n):
|
2014-09-03 13:56:02 +00:00
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{num:.1f} year{ago}'),
|
|
|
|
_('{num:.1f} years{ago}'), n)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pluralize_month(n):
|
2014-09-03 13:56:02 +00:00
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{num:.1f} month{ago}'),
|
|
|
|
_('{num:.1f} months{ago}'), n)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pluralize_week(n):
|
2014-09-03 13:56:02 +00:00
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{num:.1f} week{ago}'),
|
|
|
|
_('{num:.1f} weeks {ago}'), n)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
def pluralize_day(n):
|
2014-09-03 13:56:02 +00:00
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{num:.1f} day{ago}'),
|
|
|
|
_('{num:.1f} days{ago}'), n)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
OLDER_CHUNKS = (
|
|
|
|
(365.0, pluralize_year),
|
|
|
|
(30.0, pluralize_month),
|
|
|
|
(7.0, pluralize_week),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def _un(singular__plural, n=None):
|
|
|
|
singular, plural = singular__plural
|
|
|
|
return ungettext(singular, plural, n)
|
|
|
|
|
|
|
|
|
2014-09-17 10:32:29 +00:00
|
|
|
def naturaldatetime(date, include_seconds=False):
|
2014-07-22 21:47:01 +00:00
|
|
|
"""Convert datetime into a human natural date string."""
|
|
|
|
if not date:
|
|
|
|
return ''
|
|
|
|
|
|
|
|
right_now = timezone.now()
|
|
|
|
today = datetime(right_now.year, right_now.month,
|
|
|
|
right_now.day, tzinfo=right_now.tzinfo)
|
|
|
|
delta = right_now - date
|
|
|
|
delta_midnight = today - date
|
|
|
|
|
|
|
|
days = delta.days
|
|
|
|
hours = int(round(delta.seconds / 3600, 0))
|
|
|
|
minutes = delta.seconds / 60
|
|
|
|
seconds = delta.seconds
|
|
|
|
|
2014-09-03 13:56:02 +00:00
|
|
|
ago = ' ago'
|
2014-07-22 21:47:01 +00:00
|
|
|
if days < 0:
|
2014-09-03 13:56:02 +00:00
|
|
|
ago = ''
|
|
|
|
days = abs(days)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
if days == 0:
|
|
|
|
if hours == 0:
|
|
|
|
if minutes > 0:
|
|
|
|
minutes += float(seconds)/60
|
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{minutes:.1f} minute{ago}'),
|
|
|
|
_('{minutes:.1f} minutes{ago}'), minutes
|
|
|
|
).format(minutes=minutes, ago=ago)
|
2014-07-22 21:47:01 +00:00
|
|
|
else:
|
|
|
|
if include_seconds and seconds:
|
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{seconds} second{ago}'),
|
|
|
|
_('{seconds} seconds{ago}'), seconds
|
|
|
|
).format(seconds=seconds, ago=ago)
|
2014-07-22 21:47:01 +00:00
|
|
|
return _('just now')
|
|
|
|
else:
|
|
|
|
hours += float(minutes)/60
|
|
|
|
return ungettext(
|
2014-09-03 14:51:07 +00:00
|
|
|
_('{hours:.1f} hour{ago}'),
|
|
|
|
_('{hours:.1f} hours{ago}'), hours
|
|
|
|
).format(hours=hours, ago=ago)
|
2014-07-22 21:47:01 +00:00
|
|
|
|
|
|
|
if delta_midnight.days == 0:
|
|
|
|
return _('yesterday at {time}').format(time=date.strftime('%H:%M'))
|
|
|
|
|
|
|
|
count = 0
|
|
|
|
for chunk, pluralizefun in OLDER_CHUNKS:
|
|
|
|
if days < 7.0:
|
|
|
|
count = days + float(hours)/24
|
|
|
|
fmt = pluralize_day(count)
|
2014-09-03 14:51:07 +00:00
|
|
|
return fmt.format(num=count, ago=ago)
|
2014-07-22 21:47:01 +00:00
|
|
|
if days >= chunk:
|
|
|
|
count = (delta_midnight.days + 1) / chunk
|
2014-09-03 13:56:02 +00:00
|
|
|
count = abs(count)
|
2014-07-22 21:47:01 +00:00
|
|
|
fmt = pluralizefun(count)
|
2014-09-03 14:51:07 +00:00
|
|
|
return fmt.format(num=count, ago=ago)
|
2014-09-17 10:32:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
def naturaldate(date):
|
|
|
|
if not date:
|
|
|
|
return ''
|
|
|
|
|
|
|
|
today = timezone.now().date()
|
|
|
|
delta = today - date
|
|
|
|
days = delta.days
|
|
|
|
|
|
|
|
if days == 0:
|
|
|
|
return _('today')
|
|
|
|
elif days == 1:
|
|
|
|
return _('yesterday')
|
2014-09-26 15:05:20 +00:00
|
|
|
ago = ' ago'
|
|
|
|
if days < 0:
|
|
|
|
ago = ''
|
|
|
|
days = abs(days)
|
|
|
|
delta_midnight = today - date
|
2014-09-17 10:32:29 +00:00
|
|
|
|
|
|
|
count = 0
|
|
|
|
for chunk, pluralizefun in OLDER_CHUNKS:
|
|
|
|
if days < 7.0:
|
2014-09-26 15:05:20 +00:00
|
|
|
count = days
|
2014-09-17 10:32:29 +00:00
|
|
|
fmt = pluralize_day(count)
|
|
|
|
return fmt.format(num=count, ago=ago)
|
|
|
|
if days >= chunk:
|
|
|
|
count = (delta_midnight.days + 1) / chunk
|
|
|
|
count = abs(count)
|
|
|
|
fmt = pluralizefun(count)
|
|
|
|
return fmt.format(num=count, ago=ago)
|
2014-10-24 10:16:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
def text2int(textnum, numwords={}):
|
|
|
|
if not numwords:
|
|
|
|
units = (
|
|
|
|
'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight',
|
|
|
|
'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
|
|
|
|
'sixteen', 'seventeen', 'eighteen', 'nineteen',
|
|
|
|
)
|
|
|
|
|
|
|
|
tens = ('', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety')
|
|
|
|
|
|
|
|
scales = ['hundred', 'thousand', 'million', 'billion', 'trillion']
|
|
|
|
|
|
|
|
numwords['and'] = (1, 0)
|
|
|
|
for idx, word in enumerate(units):
|
|
|
|
numwords[word] = (1, idx)
|
|
|
|
for idx, word in enumerate(tens):
|
|
|
|
numwords[word] = (1, idx * 10)
|
|
|
|
for idx, word in enumerate(scales):
|
|
|
|
numwords[word] = (10 ** (idx * 3 or 2), 0)
|
|
|
|
|
|
|
|
current = result = 0
|
|
|
|
for word in textnum.split():
|
|
|
|
word = word.lower()
|
|
|
|
if word not in numwords:
|
|
|
|
raise Exception("Illegal word: " + word)
|
|
|
|
|
|
|
|
scale, increment = numwords[word]
|
|
|
|
current = current * scale + increment
|
|
|
|
if scale > 100:
|
|
|
|
result += current
|
|
|
|
current = 0
|
|
|
|
|
|
|
|
return result + current
|
|
|
|
|