开发者

From: "1 hour ago", To: timedelta + accuracy

开发者 https://www.devze.com 2023-02-07 17:03 出处:网络
Is there a function to \'reverse humanize\'开发者_开发知识库 times? For example, given (strings):

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号