De: “1 hora atrás”, Para: timedelta + precisão

Existe uma function para ‘reverter humanizar‘ vezes?

Por exemplo, dado (strings):

  • ‘1 minuto atrás’
  • ‘7 horas atrás’
  • ‘5 dias atrás’
  • ‘2 meses atrás’

Poderia retornar (desculpas pelo pseudo-código):

  • datetime.now () – timedelta (1 minuto), precisão (60 segundos)
  • datetime.now () – timedelta (7 horas), precisão (1 hora)
  • datetime.now () – timedelta (5 dias), precisão (1 dia)
  • datetime.now () – timedelta (2 meses), precisão (1 mês)

Eu tenho usado parsedatetime e funcionou muito bem para mim. A home page lista alguns formatos que pode manipular, por exemplo:

  • em 5 minutos
  • Daqui a 5 minutos
  • 2 horas antes do meio dia
  • 2 dias a partir de amanhã

A principal desvantagem que eu encontrei é que não tem senso de fusos horários.

Caso valha alguma coisa, aqui está uma function de wrapper que eu uso, que sempre retorna um object de datetime independentemente de a string de input ser relativa (como todos os seus exemplos) ou fixa:

 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)) 

Você não pode simplesmente escrever uma implementação simples como:

 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 

A input não parece tão variada.