python - 获取重复时间的日期时间对象列表
问题描述
问题:
我有这个特定时间的列表,例如:
repeat = ['8:15','14:28','19:43','1:21']
现在我正在尝试创建一个函数,该函数将输出n个日期时间对象的列表,如下所示:
>>> import datetime
>>>
>>> datetime.datetime.now()
datetime.datetime(2018, 10, 30, 17, 5, 55, 908000) # 2018-10-30 17:05:55
>>>
>>> output = magic(repeat, how_many=3) # <---
>>> output
[datetime.datetime(2018, 10, 30, 19, 43), datetime.datetime(2018, 10, 31, 1, 21), datetime.datetime(2018, 10, 31, 8, 15)]
>>>
>>>
>>> for i in output:
>>> print( i.strftime("%Y-%m-%d %H:%M:%S") )
2018-10-30 19:43:00
2018-10-31 01:21:00
2018-10-31 08:15:00
我的进步:
所以我用这个解决方案解决了这个问题:
def next(datetime_object, repeat):
# this function should calculate the next datetime from the datetime_object
return next_datetime_object
def magic(repeat, how_many=10):
converted = []
for i in repeat:
converted.append( datetime.datetime.strptime(i, '%H:%M') )
now = datetime.datetime.now()
output = [ next(now,converted) ]
while len(output) < how_many:
output.append(
next(output[-1] ,converted)
)
return output
虽然我陷入了创建这个next()
应该计算下一个日期时间对象的函数。
另外,如果有人有任何其他比我更好的替代解决方案,请与我分享。
编辑1(只是为了澄清)
输入:repeat = ['8:15','14:28','19:43','1:21']
功能:magic(repeat, how_many=3)
输出:[ datetime.datetime(2018, 10, 30, 19, 43), datetime.datetime(2018, 10, 31, 1, 21), datetime.datetime(2018, 10, 31, 8, 15) ]
注意:输出取决于电流datetime.datetime.now()
。在上面的例子中,当前时间是datetime.datetime(2018, 10, 30, 17, 5, 55, 908000)
解决方案
您想创建datetime.time()
对象,然后使序列循环itertools.cycle()
并与objects组合:datetime.date
import datetime
from itertools import cycle, product, repeat
from bisect import bisect
def datetime_series(*timestrings, reference=None):
times = sorted(datetime.time(*map(int, t.split(':'))) for t in timestrings)
if reference is None:
reference = datetime.datetime.now()
date, tnow = reference.date(), reference.time()
next_pos = bisect(times, tnow) # index of next time object to use
times = cycle(times + [None])
for _ in range(next_pos): # skip forward across the time objects
next(times)
for time in times:
if time is None:
# next day
date += datetime.timedelta(days=1)
time = next(times)
yield datetime.datetime.combine(date, time)
上面使用None
作为哨兵来检测日期值需要增加一个步骤,并且时间字符串被接受为单独的参数,并且您可以传入不同的参考日期(默认是使用now)。
它也是一个无穷无尽的生成器,因此您可以逐步迭代它,或者使用它itertools.slice()
来限制结果的数量。
就个人而言,我会改变使函数接受datetime.time()
对象而不是传入字符串,因此您只需对参数进行排序,而无需解析并从那里开始。
演示:
>>> from itertools import islice
>>> from pprint import pprint
>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2018, 10, 30, 17, 39, 46, 91967)
>>> m = datetime_series('8:15', '14:28', '19:43', '1:21')
>>> next(m)
datetime.datetime(2018, 10, 30, 19, 43)
>>> next(m)
datetime.datetime(2018, 10, 31, 1, 21)
>>> m = datetime_series('8:15', '14:28', '19:43', '1:21')
>>> ten_results = list(islice(m, 10))
>>> pprint(ten_results)
[datetime.datetime(2018, 10, 30, 19, 43),
datetime.datetime(2018, 10, 31, 1, 21),
datetime.datetime(2018, 10, 31, 8, 15),
datetime.datetime(2018, 10, 31, 14, 28),
datetime.datetime(2018, 10, 31, 19, 43),
datetime.datetime(2018, 11, 1, 1, 21),
datetime.datetime(2018, 11, 1, 8, 15),
datetime.datetime(2018, 11, 1, 14, 28),
datetime.datetime(2018, 11, 1, 19, 43),
datetime.datetime(2018, 11, 2, 1, 21)]
>>> question_1 = datetime.datetime(2008, 7, 31, 21, 26, 37) # https://meta.stackexchange.com/a/30138
>>> question_1_series = datetime_series('8:15', '14:28', '19:43', '1:21', reference=question_1)
>>> pprint(list(islice(question_1_series, 10)))
[datetime.datetime(2008, 8, 1, 1, 21),
datetime.datetime(2008, 8, 1, 8, 15),
datetime.datetime(2008, 8, 1, 14, 28),
datetime.datetime(2008, 8, 1, 19, 43),
datetime.datetime(2008, 8, 2, 1, 21),
datetime.datetime(2008, 8, 2, 8, 15),
datetime.datetime(2008, 8, 2, 14, 28),
datetime.datetime(2008, 8, 2, 19, 43),
datetime.datetime(2008, 8, 3, 1, 21),
datetime.datetime(2008, 8, 3, 8, 15)]
推荐阅读
- javascript - Ember transitionTo queryParams 不更新模型或 URL
- xml - XSLT 循环遍历带有条件的嵌套元素
- c++ - 如何为 C++ 映射创建自己的字符串比较对象
- c++ - 调用虚拟成员类的方法
- html - 将缩略图调整为视频大小
- plot - Autodesk Design Automation API 定义绘图设置,例如灰度/线宽
- elixir - 为模块属性累积使用映射:true
- node.js - Visual Studio 代码调试器未在 SAM Local 的断点处停止
- php - Woocommerce - 如何将产品的自定义金额添加到购物车中
- bash - “xxd -b”可以将数据转换为位串(例如:“A”→“01000001”)但是如何做相反的事情呢?