【问题标题】:how to display calculated timedelta as time in python如何在python中将计算出的timedelta显示为时间
【发布时间】:2020-12-02 15:25:47
【问题描述】:

我正在通过timew-report python 库计算存储在timewarrior 中的时间。

我正在计算时间,这是我能够做到的。而且我试图让总数在几个小时:分钟:秒内显示出来,而不是几天。

我的脚本....

#!/usr/bin/python
import sys
import datetime
from datetime import timedelta
from timewreport.parser import TimeWarriorParser #https://github.com/lauft/timew-report

parser = TimeWarriorParser(sys.stdin)

total = datetime.datetime(1, 1, 1, 0, 0)
for interval in parser.get_intervals():
    duration = interval.get_duration()
    print(duration)
    total = total + duration
print(total)

...正常工作,返回:

0:01:09
0:06:03
7:00:00
0:12:52
20:00:00
0001-01-02 03:20:04

...但我不想显示0001-01-02 03:20:04,而是说27:20:04

我如何让它变成这样的格式?

我是否采取了错误的方法来初始化 datetime.datetime(1, 1, 1, 0, 0) 这样的总数?

【问题讨论】:

  • 我不熟悉timewarrior,但您对持续时间而不是完整时间戳感兴趣,您可能希望使用datetime.timedelta 对象而不是datetime.datetime。看起来您从时间戳开始并添加了一堆时间增量;为什么不直接将 timedeltas 相加得到一个 timedelta,然后获取 total_seconds() 并自己转换为 HH:MM:SS(进行算术运算)。
  • 太棒了!你说得对,datetime.timedelta 就是我想要的!你能提供答案吗?
  • 好的,我已经完成了。
  • 你是否有一个链接到(a git o)你实现的完整代码?我会感兴趣的。
  • @a.t.查看我刚刚发布的完整脚本的答案,享受:)

标签: python taskwarrior


【解决方案1】:

total 秒从datetime 传递给timedelta 函数,如下所示:

total = your_total.timestamp()
total_time = datetime.timedelta(seconds=total) 
str(total_time) 

【讨论】:

  • 感谢@ahmadgh74 我在其他地方看到过这个,但不知道如何使用它。我认为另一个解决方案是可行的方向。
  • 您的total 是日期时间,您可以通过timestamp() 方法获取所有秒数
【解决方案2】:

假设interval.get_duration 每次都返回一个datetime.timedelta 对象,您可以将它们添加到现有的datetime.timedelta 对象中,然后在最后进行算术转换为HH:MM:SS 格式. (您需要自己进行算术运算,因为 timedelta 的默认字符串表示将使用天数,如果值超过 24 小时,则使用 HH:MM:SS,这是您不希望的。)

例如:

import datetime

total = datetime.timedelta(0)
for interval in parser.get_intervals():
    duration = interval.get_duration()
    total += duration

total_secs = int(total.total_seconds())
secs = total_secs % 60
mins = (total_secs // 60) % 60
hours = (total_secs // 3600)

print("{hours}:{mins:02}:{secs:02}".format(hours=hours, mins=mins, secs=secs))

【讨论】:

  • 我在print(f...) 行收到“无效语法”
  • @alec 好的,我将其更改为可在旧版 Python 中使用的版本。
  • @alec 现在试试吧。
  • 哦,以前的print() 是 python3 的吗?我今天早些时候使用 python 3 得到了这个,但显然我偶然发现了 python2。
  • @alec 我认为 f-strings 需要 python >= 3.6。
【解决方案3】:

对于任何对此 timewarrior 报告感兴趣的人,这是我的最终工作代码。将其放在位于 timewarrior 扩展目录中的 scriptname 中,然后像 timew scriptname tagname 一样调用以查看显示注释和给定标签的总未开票时间的时间报告(也可以在没有标签的情况下使用它来显示所有时间条目)。

#!/usr/bin/python
import sys
import datetime
from datetime import timedelta
from timewreport.parser import TimeWarriorParser #https://github.com/lauft/timew-report

parser = TimeWarriorParser(sys.stdin)

total = datetime.timedelta()
tags = ''
for interval in parser.get_intervals():
    tags = interval.get_tags()
    # this report shows only un-invoiced time, so we ignore "invoiced" time entries
    if 'invoiced' not in tags:
        # hide 'client' and 'work' tags since they clutter this report
        if 'clients' in tags:
            tags.remove('clients')
        if 'work' in tags:
            tags.remove('work')
        date = interval.get_start()
        duration = interval.get_duration()
        ant = interval.get_annotation()
        sep = ', '
        taglist = sep.join(tags)
        output = str(date.date()) + ' - ' + str(duration) + ' - ' + taglist
        if ant:
            output += ' ||| ' + str(ant)
        print(output)
        total = total + duration

print('----------------')

# We calculate the time out like this manually because we don't want numbers of hours greater than 24 to be presented as days
total_secs = int(total.total_seconds())
secs = total_secs % 60
mins = (total_secs // 60) % 60
hours = (total_secs // 3600)

# for new versions of python 3.6 and up the following could work
# print(f"{hours}:{mins:02}:{secs:02}")
# but for older python this works...
print("total = {hours}:{mins:02}:{secs:02}".format(hours=hours, mins=mins, secs=secs))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2021-12-06
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多