python - 无法使用 datetime 创建具有空天槽的计时器
问题描述
我有一个程序应该保持做某事所花费的总时间。我存储了一个值,即从“000d 00h 00m 00s”开始,持续 0 天、小时、分钟和秒。但是,如果我尝试为其添加时间,我会收到“ValueError: time data '000d 00h 00m 00s' does not match format '%jd %Hh %Mm %Ss'”。
如果我将起始字符串更改为 '001d 00h 00m 00s' 它将添加时间没问题,但我将得到一个比准确值大 24 小时的值。如果我只是删除日计数器并将其设置为“00h 00m 00s”,它也会起作用,但是一旦达到 24,它仍然会重置小时。
能够从“000d 00h 00m 00s”开始会更好,但如果这不可能,那么让小时溢出(即“25h 00m 00s”)会起作用。
from datetime import *
EmptyTime = '000d 00h 00m 00s'
EmptyTimeThatWorks = '001d 00h 00m 00s'
ExampleTime = '174d 19h 07m 53s' # June 23 7:07 PM
FMT = "%jd %Hh %Mm %Ss"
def TaskEnded(RunningTotal, TimerStartTime):
PresentTime = datetime.now().strftime(FMT) #PresnetTime is when the TaskEnded
st = datetime.strptime(TimerStartTime, FMT) #Brings things into the right format
pt = datetime.strptime(PresentTime, FMT) #Brings things into the right format
rt = datetime.strptime(RunningTotal, FMT) #Brings things into the right format, but EmptyTime cant be
# conveted to the right time because day '0' doenst exist
# while hour, minute, and second 0 do
NewTotal = rt + (pt - st) #takes the running total and adds the timer value, which is the difference of start and end times
NewTotal2 = datetime.strftime(NewTotal, FMT) # Puts the Datetime value back into the right format FMT
print(NewTotal2)
return NewTotal2
TaskEnded(EmptyTimeThatWorks, ExampleTime)
TaskEnded(EmptyTime, ExampleTime)
解决方案
这就是我将经过的时间保存在 a 中timedelta
并编写遵循 PEP 8 准则的代码的意思:
from datetime import *
def task_ended(running_total, timer_start_time, fmt="%B %d, %Y %I:%M %p"):
""" Add time elapsed between timer_start_time and now to
running_total timedelta and return it.
"""
present_time = datetime.now() # When task ended.
# Convert timer_start_time string into a datetime using fmt string.
start_time = datetime.strptime(timer_start_time, fmt)
# Add time elapsed between present time and timer start time to running
# total and return it.
return running_total + (present_time - start_time)
def format_timedelta(td):
""" Format timedelta into custom string representation. """
days = td.days
hours, remainder = divmod(td.seconds, 3600)
mins, secs = divmod(remainder, 60)
return '{:03}d {:02}h {:02}m {:02}s'.format(days, hours, mins, secs)
running_total = timedelta()
example_start_time = 'June 25, 2019 5:00 PM'
running_total = task_ended(running_total, example_start_time)
print('running total:', format_timedelta(running_total))
print()
running_total = timedelta()
example_start_time = 'June 23, 2019 7:07 PM'
running_total = task_ended(running_total, example_start_time)
print('running total:', format_timedelta(running_total))
这是一种将运行中的总字符串解析为 a 的方法timedelta
(基于对问题如何timedelta
从简单字符串构造对象的几个答案):
import re
regex = re.compile(r'^((?P<days>[\d]+?)d)? *'
r'((?P<hours>[\d]+?)h)? *'
r'((?P<minutes>[\d]+?)m)? *'
r'((?P<seconds>[\d]+?)s)?$')
def parse_timedelta(time_str):
"""
Parse a time string e.g. (2h 13m) into a timedelta object.
Modified from virhilo & Peter's answers at https://stackoverflow.com/a/4628148/355230
:param time_str: A string identifying a duration. (eg. 2h 13m)
:return datetime.timedelta: A datetime.timedelta object
"""
parts = regex.match(time_str)
assert parts is not None, "Could not parse any time information from '{}'".format(time_str)
time_params = {name: float(param) for name, param in parts.groupdict().items() if param}
return timedelta(**time_params)
# Test string parser function.
test_str = '000d 21h 40m 53s'
td = parse_timedelta(test_str)
assert format_timedelta(td) == test_str
test_str = '002d 19h 33m 53s'
td = parse_timedelta(test_str)
assert format_timedelta(td) == test_str
推荐阅读
- android - 自定义键盘:ASCII 代码与 KEYCODE
- algorithm - 在大量文件中搜索固定字符串的静态列表
- excel - 如果活动单元格在表格列中,则仅复制单元格值
- python - Python 日志错误“非类型”
- amazon-web-services - KAFKA 消费者设置在本地代理后面。生产者在 AWS
- javascript - 使用来自 javascript 的 get 方法访问 php 时未定义值
- c# - 有没有办法将 RichTextBox 添加到适用于 Android 的 C# Xamarin 项目?
- listview - 如何在双 ListView 选择系统上实现过滤器?
- ubuntu - 如何在 emacs 27、ubuntu 18 上启动 emacsclient
- json - 如何使用未知密钥解码 json