带有负值的Python timedelta问题

Dre*_*ols 30 python timedelta

嗨,我需要一些帮助才能理解为什么会这样.我有一种方法来跟踪事件程序中的"剩余时间":

def get_program_time_budget(self):
    return self.estimated_duration-self.get_program_duration() 
Run Code Online (Sandbox Code Playgroud)

当estimated_duration> self.get_program_duration()时,所有这些都很好,但是当事情变得有趣时.

结果显示给用户:

Estimated   11 hours    Allocated       10 hours 55 minutes     Remaining       5 minutes
Run Code Online (Sandbox Code Playgroud)

当结果为负时,它会这样做:

Estimated   11 hours    Allocated       11 hours 5 minutes  Remaining       -1 day 23 hours 55 minutes
Run Code Online (Sandbox Code Playgroud)

任何想法如何获得结果-5分钟?

编辑:这是timedelta格式化程序(注意这是一个Django过滤器,因此接收时间值作为str - 但它存储为timedelta):

def format_duration(value):
  try:
    delim = ':'
    toks = value.split(',')
    hour = minute = ''
    d_string = value.count('day') and toks[0] or ''
    h, m, s = d_string and toks[-1].strip().split(delim) or value.split(delim)
    try:
        hour = int(h)
    except:
        pass
    try:
        minute = int(m)
    except:
        pass  
    h_string = "%s%s%s" % (hour and hour or '', (hour and ' hour' or ''),(hour and hour > 1 and 's' or '')  )
    m_string = "%s%s%s" % (minute and minute or '', (minute and ' minute' or ''),(minute and minute > 1 and 's' or ''))
    return "%s %s %s" % (d_string, h_string, m_string)
  except Exception, e:
    logging.error("Error in format_duration -> %s. Duration value=%s" % (e, value))
    return ''v 
Run Code Online (Sandbox Code Playgroud)

And*_*ark 42

如果您使用Python 2.7或更高版本,您可以使用timedelta.total_seconds()获得float的timedelta的表示形式的秒数的正数或负数.

>>> datetime.timedelta(-1, 86100).total_seconds()
-300.0
Run Code Online (Sandbox Code Playgroud)

您应该可以使用它来相当容易地计算分钟数.

如果您不使用Python 2.7,则可以使用文档中的以下等效公式:

(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6
Run Code Online (Sandbox Code Playgroud)

编辑:看起来您可能正在使用timedelta的默认字符串表示来显示结果,因此我的原始答案可能没那么有用.为了显示结果,我会建议这样的东西:

def get_program_time_budget(self):
    td = self.estimated_duration-self.get_program_duration()
    if td.days < 0:
        return '-' + str(datetime.timedelta() - td)
    return str(td)
Run Code Online (Sandbox Code Playgroud)

现在这将返回一个字符串而不是一个timedelta,而对于负时间,它会将' - '添加到正时间delta.


dan*_*n04 16

为什么?

可能是作为方式的无意识的副作用//并被%定义.

可能是因为它使实现datetime类更容易.纪元前的五分钟是23:55,而不是0:-5.

这并不重要.只知道它是如何days,seconds以及microseconds得到规范化.并且它可以很容易地解决.

def format_timedelta(td):
    if td < timedelta(0):
        return '-' + format_timedelta(-td)
    else:
        # Change this to format positive timedeltas the way you want
        return str(td)

 >>> format_timedelta(timedelta(minutes=-5))
 '-0:05:00'
Run Code Online (Sandbox Code Playgroud)

  • 这是如此简单而又天才.谢谢! (3认同)