如何在 python 中将一个时段分解为一组子时段(小时、刻钟和分钟)
how to decompose a period into a set of subperiods (hour, quarter-hour and minute) in python
我想将一个周期分成几个预定义大小的子周期。
这是一个例子:
在 2021-04-11 15:03:00 和 2021-04-11 18:03:00 之间,分解为小时、刻钟和分钟。预期结果是(无具体顺序):
2021-04-11 15:03:00 (the minute)
2021-04-11 15:04:00 (the minute)
2021-04-11 15:05:00 (the minute)
2021-04-11 15:06:00 (the minute)
2021-04-11 15:07:00 (the minute)
2021-04-11 15:08:00 (the minute)
2021-04-11 15:09:00 (the minute)
2021-04-11 15:10:00 (the minute)
2021-04-11 15:11:00 (the minute)
2021-04-11 15:12:00 (the minute)
2021-04-11 15:13:00 (the minute)
2021-04-11 15:14:00 (the minute)
2021-04-11 15:15:00 (the quarter-hour)
2021-04-11 15:30:00 (the quarter-hour)
2021-04-11 15:45:00 (the quarter-hour)
2021-04-11 16:00:00 (the hour)
2021-04-11 17:00:00 (the hour)
2021-04-11 18:00:00 (the minute)
2021-04-11 18:01:00 (the minute)
2021-04-11 18:02:00 (the minute)
我当前的代码:
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
def floor_dt(dt, delta):
return dt - (dt - datetime.min) % delta
def list_dt(start, end, subperiod, indice):
temp = start
min = ceil_dt(temp, timedelta(minutes=subperiod[indice]))
print(f'\nstart {start}')
print(f'end {end}')
print(f'subperiod {subperiod}')
print(f'indice {indice}')
print(f'min {min}')
while temp + timedelta(minutes=subperiod[indice]) <= floor_dt(end, timedelta(minutes=subperiod[indice])) :
print(f'result {ceil_dt(temp, timedelta(minutes=subperiod[indice]))}')
temp = temp + timedelta(minutes=subperiod[indice])
max = ceil_dt(temp, timedelta(minutes=subperiod[indice]))
print(f'max {max}')
if min != start:
print("other min")
indice = indice + 1
list_dt(start, min, subperiod, indice)
# if max != end:
# print("other max")
# indice = indice + 1
# list_dt(max, end, subperiod, indice)
subperiod = [60, 15, 1]
indice = 0
start = datetime(2021, 4, 11, 15, 3, 0)
end = datetime(2021, 4, 11, 18, 3, 0)
list_dt(start, end, subperiod, indice)
我找不到如何正确输入最小值和最大值部分。
我不确定我们是否应该使用递归。有人有想法吗?
您可以使用 while
循环:
from datetime import datetime, timedelta as td
def list_dt(d1, d2):
while d1 < d2:
yield d1
if not d1.minute and d1+td(hours = 1) <= d2:
d1 += td(hours = 1)
elif not d1.minute%15 and d1+td(minutes = 15) <= d2:
d1 += td(minutes = 15)
else:
d1 += td(minutes = 1)
for a, b in [[datetime(2021, 4, 11, 15, 3, 0), datetime(2021, 4, 11, 18, 3, 0)], [datetime(2021, 4, 11, 15, 0, 0), datetime(2021, 4, 11, 18, 0, 0)], [datetime(2021, 4, 11, 15, 15, 0), datetime(2021, 4, 11, 18, 30, 0)]]:
for i in list_dt(a, b):
print(str(i))
print('-'*20)
输出:
2021-04-11 15:03:00
2021-04-11 15:04:00
2021-04-11 15:05:00
2021-04-11 15:06:00
2021-04-11 15:07:00
2021-04-11 15:08:00
2021-04-11 15:09:00
2021-04-11 15:10:00
2021-04-11 15:11:00
2021-04-11 15:12:00
2021-04-11 15:13:00
2021-04-11 15:14:00
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 17:00:00
2021-04-11 18:00:00
2021-04-11 18:01:00
2021-04-11 18:02:00
--------------------
2021-04-11 15:00:00
2021-04-11 16:00:00
2021-04-11 17:00:00
--------------------
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 17:00:00
2021-04-11 18:00:00
2021-04-11 18:15:00
--------------------
您所描述的内容已通过 datetime 的 rrule 提供。作为一个基本示例,您可以像这样编写一个函数:
import dateutil.rrule as rrule
from datetime import datetime, timedelta
# function to round to nearest n time
def round_nearest(date, **kwargs):
secs = timedelta(**kwargs).total_seconds()
return datetime.fromtimestamp(date.timestamp() + secs - date.timestamp() % secs)
# function to return per OP's post
def hours_aligned(start, end, inc = True):
print("Minutes")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.MINUTELY, dtstart=start)
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
print("Hours")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.HOURLY, dtstart=start)
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
print("Quarter Hours")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.MINUTELY, interval=15, dtstart=round_nearest(start, minutes=15))
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
start = datetime(2021, 4, 11, 15, 3, 0)
end = datetime(2021, 4, 11, 18, 3, 0)
for x in hours_aligned(start, end, inc=True):
print(x)
Minutes
2021-04-11 15:03:00
2021-04-11 15:04:00
2021-04-11 15:05:00
2021-04-11 15:06:00
2021-04-11 15:07:00
2021-04-11 15:08:00
2021-04-11 15:09:00
2021-04-11 15:10:00
2021-04-11 15:11:00
2021-04-11 15:12:00
2021-04-11 15:13:00
2021-04-11 15:14:00
2021-04-11 15:15:00
2021-04-11 15:16:00
2021-04-11 15:17:00
2021-04-11 15:18:00
2021-04-11 15:19:00
2021-04-11 15:20:00
2021-04-11 15:21:00
2021-04-11 15:22:00
2021-04-11 15:23:00
2021-04-11 15:24:00
2021-04-11 15:25:00
2021-04-11 15:26:00
2021-04-11 15:27:00
2021-04-11 15:28:00
2021-04-11 15:29:00
2021-04-11 15:30:00
2021-04-11 15:31:00
2021-04-11 15:32:00
2021-04-11 15:33:00
2021-04-11 15:34:00
2021-04-11 15:35:00
2021-04-11 15:36:00
2021-04-11 15:37:00
2021-04-11 15:38:00
2021-04-11 15:39:00
2021-04-11 15:40:00
2021-04-11 15:41:00
2021-04-11 15:42:00
2021-04-11 15:43:00
2021-04-11 15:44:00
2021-04-11 15:45:00
2021-04-11 15:46:00
2021-04-11 15:47:00
2021-04-11 15:48:00
2021-04-11 15:49:00
2021-04-11 15:50:00
2021-04-11 15:51:00
2021-04-11 15:52:00
2021-04-11 15:53:00
2021-04-11 15:54:00
2021-04-11 15:55:00
2021-04-11 15:56:00
2021-04-11 15:57:00
2021-04-11 15:58:00
2021-04-11 15:59:00
2021-04-11 16:00:00
2021-04-11 16:01:00
2021-04-11 16:02:00
2021-04-11 16:03:00
2021-04-11 16:04:00
2021-04-11 16:05:00
2021-04-11 16:06:00
2021-04-11 16:07:00
2021-04-11 16:08:00
2021-04-11 16:09:00
2021-04-11 16:10:00
2021-04-11 16:11:00
2021-04-11 16:12:00
2021-04-11 16:13:00
2021-04-11 16:14:00
2021-04-11 16:15:00
2021-04-11 16:16:00
2021-04-11 16:17:00
2021-04-11 16:18:00
2021-04-11 16:19:00
2021-04-11 16:20:00
2021-04-11 16:21:00
2021-04-11 16:22:00
2021-04-11 16:23:00
2021-04-11 16:24:00
2021-04-11 16:25:00
2021-04-11 16:26:00
2021-04-11 16:27:00
2021-04-11 16:28:00
2021-04-11 16:29:00
2021-04-11 16:30:00
2021-04-11 16:31:00
2021-04-11 16:32:00
2021-04-11 16:33:00
2021-04-11 16:34:00
2021-04-11 16:35:00
2021-04-11 16:36:00
2021-04-11 16:37:00
2021-04-11 16:38:00
2021-04-11 16:39:00
2021-04-11 16:40:00
2021-04-11 16:41:00
2021-04-11 16:42:00
2021-04-11 16:43:00
2021-04-11 16:44:00
2021-04-11 16:45:00
2021-04-11 16:46:00
2021-04-11 16:47:00
2021-04-11 16:48:00
2021-04-11 16:49:00
2021-04-11 16:50:00
2021-04-11 16:51:00
2021-04-11 16:52:00
2021-04-11 16:53:00
2021-04-11 16:54:00
2021-04-11 16:55:00
2021-04-11 16:56:00
2021-04-11 16:57:00
2021-04-11 16:58:00
2021-04-11 16:59:00
2021-04-11 17:00:00
2021-04-11 17:01:00
2021-04-11 17:02:00
2021-04-11 17:03:00
2021-04-11 17:04:00
2021-04-11 17:05:00
2021-04-11 17:06:00
2021-04-11 17:07:00
2021-04-11 17:08:00
2021-04-11 17:09:00
2021-04-11 17:10:00
2021-04-11 17:11:00
2021-04-11 17:12:00
2021-04-11 17:13:00
2021-04-11 17:14:00
2021-04-11 17:15:00
2021-04-11 17:16:00
2021-04-11 17:17:00
2021-04-11 17:18:00
2021-04-11 17:19:00
2021-04-11 17:20:00
2021-04-11 17:21:00
2021-04-11 17:22:00
2021-04-11 17:23:00
2021-04-11 17:24:00
2021-04-11 17:25:00
2021-04-11 17:26:00
2021-04-11 17:27:00
2021-04-11 17:28:00
2021-04-11 17:29:00
2021-04-11 17:30:00
2021-04-11 17:31:00
2021-04-11 17:32:00
2021-04-11 17:33:00
2021-04-11 17:34:00
2021-04-11 17:35:00
2021-04-11 17:36:00
2021-04-11 17:37:00
2021-04-11 17:38:00
2021-04-11 17:39:00
2021-04-11 17:40:00
2021-04-11 17:41:00
2021-04-11 17:42:00
2021-04-11 17:43:00
2021-04-11 17:44:00
2021-04-11 17:45:00
2021-04-11 17:46:00
2021-04-11 17:47:00
2021-04-11 17:48:00
2021-04-11 17:49:00
2021-04-11 17:50:00
2021-04-11 17:51:00
2021-04-11 17:52:00
2021-04-11 17:53:00
2021-04-11 17:54:00
2021-04-11 17:55:00
2021-04-11 17:56:00
2021-04-11 17:57:00
2021-04-11 17:58:00
2021-04-11 17:59:00
2021-04-11 18:00:00
2021-04-11 18:01:00
2021-04-11 18:02:00
2021-04-11 18:03:00
Hours
2021-04-11 15:03:00
2021-04-11 16:03:00
2021-04-11 17:03:00
2021-04-11 18:03:00
Quarter Hours
2021-04-11 15:03:00
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 16:15:00
2021-04-11 16:30:00
2021-04-11 16:45:00
2021-04-11 17:00:00
2021-04-11 17:15:00
2021-04-11 17:30:00
2021-04-11 17:45:00
2021-04-11 18:00:00
2021-04-11 18:03:00
我创建了 3 条规则,按分钟(即 MINUTELY)、按分钟但间隔 15 分钟,然后按小时(即 HOURLY)。 Inc 只是您是否要包括开始结束。
我想将一个周期分成几个预定义大小的子周期。
这是一个例子:
在 2021-04-11 15:03:00 和 2021-04-11 18:03:00 之间,分解为小时、刻钟和分钟。预期结果是(无具体顺序):
2021-04-11 15:03:00 (the minute)
2021-04-11 15:04:00 (the minute)
2021-04-11 15:05:00 (the minute)
2021-04-11 15:06:00 (the minute)
2021-04-11 15:07:00 (the minute)
2021-04-11 15:08:00 (the minute)
2021-04-11 15:09:00 (the minute)
2021-04-11 15:10:00 (the minute)
2021-04-11 15:11:00 (the minute)
2021-04-11 15:12:00 (the minute)
2021-04-11 15:13:00 (the minute)
2021-04-11 15:14:00 (the minute)
2021-04-11 15:15:00 (the quarter-hour)
2021-04-11 15:30:00 (the quarter-hour)
2021-04-11 15:45:00 (the quarter-hour)
2021-04-11 16:00:00 (the hour)
2021-04-11 17:00:00 (the hour)
2021-04-11 18:00:00 (the minute)
2021-04-11 18:01:00 (the minute)
2021-04-11 18:02:00 (the minute)
我当前的代码:
def ceil_dt(dt, delta):
return dt + (datetime.min - dt) % delta
def floor_dt(dt, delta):
return dt - (dt - datetime.min) % delta
def list_dt(start, end, subperiod, indice):
temp = start
min = ceil_dt(temp, timedelta(minutes=subperiod[indice]))
print(f'\nstart {start}')
print(f'end {end}')
print(f'subperiod {subperiod}')
print(f'indice {indice}')
print(f'min {min}')
while temp + timedelta(minutes=subperiod[indice]) <= floor_dt(end, timedelta(minutes=subperiod[indice])) :
print(f'result {ceil_dt(temp, timedelta(minutes=subperiod[indice]))}')
temp = temp + timedelta(minutes=subperiod[indice])
max = ceil_dt(temp, timedelta(minutes=subperiod[indice]))
print(f'max {max}')
if min != start:
print("other min")
indice = indice + 1
list_dt(start, min, subperiod, indice)
# if max != end:
# print("other max")
# indice = indice + 1
# list_dt(max, end, subperiod, indice)
subperiod = [60, 15, 1]
indice = 0
start = datetime(2021, 4, 11, 15, 3, 0)
end = datetime(2021, 4, 11, 18, 3, 0)
list_dt(start, end, subperiod, indice)
我找不到如何正确输入最小值和最大值部分。 我不确定我们是否应该使用递归。有人有想法吗?
您可以使用 while
循环:
from datetime import datetime, timedelta as td
def list_dt(d1, d2):
while d1 < d2:
yield d1
if not d1.minute and d1+td(hours = 1) <= d2:
d1 += td(hours = 1)
elif not d1.minute%15 and d1+td(minutes = 15) <= d2:
d1 += td(minutes = 15)
else:
d1 += td(minutes = 1)
for a, b in [[datetime(2021, 4, 11, 15, 3, 0), datetime(2021, 4, 11, 18, 3, 0)], [datetime(2021, 4, 11, 15, 0, 0), datetime(2021, 4, 11, 18, 0, 0)], [datetime(2021, 4, 11, 15, 15, 0), datetime(2021, 4, 11, 18, 30, 0)]]:
for i in list_dt(a, b):
print(str(i))
print('-'*20)
输出:
2021-04-11 15:03:00
2021-04-11 15:04:00
2021-04-11 15:05:00
2021-04-11 15:06:00
2021-04-11 15:07:00
2021-04-11 15:08:00
2021-04-11 15:09:00
2021-04-11 15:10:00
2021-04-11 15:11:00
2021-04-11 15:12:00
2021-04-11 15:13:00
2021-04-11 15:14:00
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 17:00:00
2021-04-11 18:00:00
2021-04-11 18:01:00
2021-04-11 18:02:00
--------------------
2021-04-11 15:00:00
2021-04-11 16:00:00
2021-04-11 17:00:00
--------------------
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 17:00:00
2021-04-11 18:00:00
2021-04-11 18:15:00
--------------------
您所描述的内容已通过 datetime 的 rrule 提供。作为一个基本示例,您可以像这样编写一个函数:
import dateutil.rrule as rrule
from datetime import datetime, timedelta
# function to round to nearest n time
def round_nearest(date, **kwargs):
secs = timedelta(**kwargs).total_seconds()
return datetime.fromtimestamp(date.timestamp() + secs - date.timestamp() % secs)
# function to return per OP's post
def hours_aligned(start, end, inc = True):
print("Minutes")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.MINUTELY, dtstart=start)
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
print("Hours")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.HOURLY, dtstart=start)
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
print("Quarter Hours")
if inc: yield start # remove if you don't require start
rule = rrule.rrule(rrule.MINUTELY, interval=15, dtstart=round_nearest(start, minutes=15))
for x in rule.between(start, end, inc = False):
yield x
if inc: yield end # remove if you don't require end
start = datetime(2021, 4, 11, 15, 3, 0)
end = datetime(2021, 4, 11, 18, 3, 0)
for x in hours_aligned(start, end, inc=True):
print(x)
Minutes
2021-04-11 15:03:00
2021-04-11 15:04:00
2021-04-11 15:05:00
2021-04-11 15:06:00
2021-04-11 15:07:00
2021-04-11 15:08:00
2021-04-11 15:09:00
2021-04-11 15:10:00
2021-04-11 15:11:00
2021-04-11 15:12:00
2021-04-11 15:13:00
2021-04-11 15:14:00
2021-04-11 15:15:00
2021-04-11 15:16:00
2021-04-11 15:17:00
2021-04-11 15:18:00
2021-04-11 15:19:00
2021-04-11 15:20:00
2021-04-11 15:21:00
2021-04-11 15:22:00
2021-04-11 15:23:00
2021-04-11 15:24:00
2021-04-11 15:25:00
2021-04-11 15:26:00
2021-04-11 15:27:00
2021-04-11 15:28:00
2021-04-11 15:29:00
2021-04-11 15:30:00
2021-04-11 15:31:00
2021-04-11 15:32:00
2021-04-11 15:33:00
2021-04-11 15:34:00
2021-04-11 15:35:00
2021-04-11 15:36:00
2021-04-11 15:37:00
2021-04-11 15:38:00
2021-04-11 15:39:00
2021-04-11 15:40:00
2021-04-11 15:41:00
2021-04-11 15:42:00
2021-04-11 15:43:00
2021-04-11 15:44:00
2021-04-11 15:45:00
2021-04-11 15:46:00
2021-04-11 15:47:00
2021-04-11 15:48:00
2021-04-11 15:49:00
2021-04-11 15:50:00
2021-04-11 15:51:00
2021-04-11 15:52:00
2021-04-11 15:53:00
2021-04-11 15:54:00
2021-04-11 15:55:00
2021-04-11 15:56:00
2021-04-11 15:57:00
2021-04-11 15:58:00
2021-04-11 15:59:00
2021-04-11 16:00:00
2021-04-11 16:01:00
2021-04-11 16:02:00
2021-04-11 16:03:00
2021-04-11 16:04:00
2021-04-11 16:05:00
2021-04-11 16:06:00
2021-04-11 16:07:00
2021-04-11 16:08:00
2021-04-11 16:09:00
2021-04-11 16:10:00
2021-04-11 16:11:00
2021-04-11 16:12:00
2021-04-11 16:13:00
2021-04-11 16:14:00
2021-04-11 16:15:00
2021-04-11 16:16:00
2021-04-11 16:17:00
2021-04-11 16:18:00
2021-04-11 16:19:00
2021-04-11 16:20:00
2021-04-11 16:21:00
2021-04-11 16:22:00
2021-04-11 16:23:00
2021-04-11 16:24:00
2021-04-11 16:25:00
2021-04-11 16:26:00
2021-04-11 16:27:00
2021-04-11 16:28:00
2021-04-11 16:29:00
2021-04-11 16:30:00
2021-04-11 16:31:00
2021-04-11 16:32:00
2021-04-11 16:33:00
2021-04-11 16:34:00
2021-04-11 16:35:00
2021-04-11 16:36:00
2021-04-11 16:37:00
2021-04-11 16:38:00
2021-04-11 16:39:00
2021-04-11 16:40:00
2021-04-11 16:41:00
2021-04-11 16:42:00
2021-04-11 16:43:00
2021-04-11 16:44:00
2021-04-11 16:45:00
2021-04-11 16:46:00
2021-04-11 16:47:00
2021-04-11 16:48:00
2021-04-11 16:49:00
2021-04-11 16:50:00
2021-04-11 16:51:00
2021-04-11 16:52:00
2021-04-11 16:53:00
2021-04-11 16:54:00
2021-04-11 16:55:00
2021-04-11 16:56:00
2021-04-11 16:57:00
2021-04-11 16:58:00
2021-04-11 16:59:00
2021-04-11 17:00:00
2021-04-11 17:01:00
2021-04-11 17:02:00
2021-04-11 17:03:00
2021-04-11 17:04:00
2021-04-11 17:05:00
2021-04-11 17:06:00
2021-04-11 17:07:00
2021-04-11 17:08:00
2021-04-11 17:09:00
2021-04-11 17:10:00
2021-04-11 17:11:00
2021-04-11 17:12:00
2021-04-11 17:13:00
2021-04-11 17:14:00
2021-04-11 17:15:00
2021-04-11 17:16:00
2021-04-11 17:17:00
2021-04-11 17:18:00
2021-04-11 17:19:00
2021-04-11 17:20:00
2021-04-11 17:21:00
2021-04-11 17:22:00
2021-04-11 17:23:00
2021-04-11 17:24:00
2021-04-11 17:25:00
2021-04-11 17:26:00
2021-04-11 17:27:00
2021-04-11 17:28:00
2021-04-11 17:29:00
2021-04-11 17:30:00
2021-04-11 17:31:00
2021-04-11 17:32:00
2021-04-11 17:33:00
2021-04-11 17:34:00
2021-04-11 17:35:00
2021-04-11 17:36:00
2021-04-11 17:37:00
2021-04-11 17:38:00
2021-04-11 17:39:00
2021-04-11 17:40:00
2021-04-11 17:41:00
2021-04-11 17:42:00
2021-04-11 17:43:00
2021-04-11 17:44:00
2021-04-11 17:45:00
2021-04-11 17:46:00
2021-04-11 17:47:00
2021-04-11 17:48:00
2021-04-11 17:49:00
2021-04-11 17:50:00
2021-04-11 17:51:00
2021-04-11 17:52:00
2021-04-11 17:53:00
2021-04-11 17:54:00
2021-04-11 17:55:00
2021-04-11 17:56:00
2021-04-11 17:57:00
2021-04-11 17:58:00
2021-04-11 17:59:00
2021-04-11 18:00:00
2021-04-11 18:01:00
2021-04-11 18:02:00
2021-04-11 18:03:00
Hours
2021-04-11 15:03:00
2021-04-11 16:03:00
2021-04-11 17:03:00
2021-04-11 18:03:00
Quarter Hours
2021-04-11 15:03:00
2021-04-11 15:15:00
2021-04-11 15:30:00
2021-04-11 15:45:00
2021-04-11 16:00:00
2021-04-11 16:15:00
2021-04-11 16:30:00
2021-04-11 16:45:00
2021-04-11 17:00:00
2021-04-11 17:15:00
2021-04-11 17:30:00
2021-04-11 17:45:00
2021-04-11 18:00:00
2021-04-11 18:03:00
我创建了 3 条规则,按分钟(即 MINUTELY)、按分钟但间隔 15 分钟,然后按小时(即 HOURLY)。 Inc 只是您是否要包括开始结束。