От: "1 час назад", до: timedelta + точность

Есть ли функция для "обратной гуманизации" времен?

Например, задано (строки):

  • "1 минуту назад"
  • '7 часов назад'
  • '5 дней назад'
  • '2 месяца назад'

Может вернуться (извините за псевдокод):

  • datetime.now () - timedelta (1 минута), точность (60 секунд)
  • datetime.now () - timedelta (7 часов), точность (1 час)
  • datetime.now () - timedelta (5 дней), точность (1 день)
  • datetime.now () - timedelta (2 месяца), точность (1 месяц)

2 ответа

Вы не можете просто написать простую реализацию, такую ​​как:

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

Входные данные не выглядят такими разнообразными.

Я использовал parsedatetime, и он работал довольно хорошо для меня. На домашней странице перечислены некоторые форматы, которые он может обрабатывать, например:

  • через 5 минут
  • Через 5 минут
  • За 2 часа до полудня
  • 2 дня с завтрашнего дня

Основным недостатком, который я обнаружил, является отсутствие часовых поясов.

Если это чего-то стоит, вот функция-обертка, которую я использую, которая всегда возвращает datetime объект независимо от того, является ли входная строка относительной (как все ваши примеры) или фиксированной:

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))
Другие вопросы по тегам