【问题标题】:From: "1 hour ago", To: timedelta + accuracy从:“1 小时前”,到:timedelta + 准确度
【发布时间】:2011-06-17 21:36:22
【问题描述】:

是否有“逆转人性化”时代的功能?

例如,给定(字符串):

  • '1 分钟前'
  • '7 小时前'
  • '5 天前'
  • '2 个月前'

可以返回(为伪代码道歉):

  • datetime.now() - timedelta(1 分钟),准确度(60 秒)
  • datetime.now() - timedelta(7 小时),准确度(1 小时)
  • datetime.now() - timedelta(5 天),准确度(1 天)
  • datetime.now() - timedelta(2 个月),准确度(1 个月)

【问题讨论】:

  • “准确度”是什么意思?请为您提供的示例提供您期望的输出。
  • @RobBednark 你在重提旧问题? :) 准确度 ~= 这个时间段的可能范围。例如。 “两天前”的时间实际上涵盖了 48 小时到 72 小时前的时间段。两天前的直接转换将是 48 小时前的瞬间,但这并不能表示该事件实际上可能发生在此之前的 23 小时 59 分钟,(或者如果人性化时间向上取整,则为 12 小时之后)。因此convert(humanized_string) 可能会返回[time, accuracy(before, after)],例如convert('two days ago') = [time(48hours), accuracy(-12hours, +24hours)]

标签: python datetime time humanize


【解决方案1】:

我一直在使用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))

【讨论】:

  • 您可以尝试通过定位数字并递增或递减它并找出两个解析的日期时间之间的差异来使 parsedatetime 为您提供精确度。
  • @Paul 更容易检查返回值和now() 之间的差异。
  • 我指的是 OP 想要的精度(或分辨率),例如“这具体如何指定一个时刻”?即,“在 5 分钟内”的分辨率为 1 分钟(它可以指代大约 4 到 6 分钟的任何时间),而“2 个月前”的分辨率约为 30 天,因为它可以指该月的任何时间.
  • @Paul 是的,我理解你。 “在 2 小时内”将返回与 now() 相同的分钟和秒数。也许这有助于您理解我建议的方法?
【解决方案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

输入看起来并没有变化。

【讨论】:

    猜你喜欢
    • 2018-06-06
    • 2015-09-25
    • 1970-01-01
    • 2017-02-04
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    相关资源
    最近更新 更多