From: "1 hour ago", To: timedelta + accuracy
Is there a function to 'reverse humanize'开发者_开发知识库 times?
For example, given (strings):
- '1 minute ago'
- '7 hours ago'
- '5 days ago'
- '2 months ago'
Could return (apologies for the pseudo-code):
- datetime.now() - timedelta (1 minute), accuracy (60 seconds)
- datetime.now() - timedelta (7 hours), accuracy (1 hour)
- datetime.now() - timedelta (5 days), accuracy (1 day)
- datetime.now() - timedelta (2 months), accuracy (1 month)
I've been using parsedatetime and it's worked rather well for me. The home page lists some formats it can handle, e.g.:
- in 5 minutes
- 5 minutes from now
- 2 hours before noon
- 2 days from tomorrow
The major downside I've found is that it has no sense of timezones.
In case it's worth anything, here's a wrapper function I use, which always returns a datetime
object regardless of whether the input string is relative (like all your examples) or fixed:
def parse_datetime(datetime_string):
datetime_parser = parsedatetime.Calendar(parsedatetime_consts.Constants())
timestamp = datetime_parser.parse(datetime_string)
if len(timestamp) == 2:
if timestamp[1] == 0:
raise ValueError(u'Failed to parse datetime: %s' % datetime_string)
timestamp = timestamp[0]
return datetime.fromtimestamp(time.mktime(timestamp))
Can you not just write a simple implementation yourself such as:
import datetime
def parsedatetime(str_val):
parts = str_val.split(' ')
if len(parts) != 3 and parts[2] != 'ago':
raise Exception("can't parse %s" % str_val)
try:
interval = int(parts[0])
except ValueError,e :
raise Exception("can't parse %s" % str_val)
desc = parts[1]
if 'second' in desc:
td = datetime.timedelta(seconds=interval)
elif 'minute' in desc:
td = datetime.timedelta(minutes=interval)
elif 'hour' in desc:
td = datetime.timedelta(minutes=interval*60)
elif 'day' in desc:
td = datetime.timedelta(days=interval)
else:
raise Exception("cant parse %s" % str_val)
answer = datetime.datetime.now - td
return answer
The input doesn't look that varied.
精彩评论