根据一周的标记分区分割日期时间间隔

Ric*_*ing 6 python datetime date-arithmetic

我有shift一个日期时间间隔(一对datetimes)。我的周有一个带标签的分区(每周都是一样的:分为几个部分,每个部分都有一个标签)。我想shift根据一周的划分分成标记部分(即分成几个子区间)。

例子。假设shift区间为2019-10-21 18:30- 2019-10-22 08:00,一周的划分如下:周一至周五 07:00 - 19:00 有 label A,本周其余时间有 label B。在这种情况下,分割shift应该是以下标记的子区间列表:

  • 2019-10-21 18:30-2019-10-21 19:00带标签A
  • 2019-10-21 19:00-2019-10-22 07:00带标签B,以及
  • 2019-10-22 07:00-2019-10-22 08:00带标签A

一般情况下我该如何做到这一点?

输入:一个datetime间隔(对)和一周的标记分区(如何最好地表示这一点?)

输出:datetime标记间隔(对)的列表。

请注意,shift可以在一周内开始并在另一周内结束(例如周日晚上到周一早上);每周都有相同的标记分区。

WTR*_*per -2

您尚未定义如果您的轮班限制之一(开始或结束)位于一周的一部分内而另一限制位于一周外,会发生什么情况。例如,如果您有,会发生什么

2019-10-21 18:30 - 2019-10-21 19:00
Run Code Online (Sandbox Code Playgroud)

是A还是B?您可以制定规则,如果一个部分在“B”中,则标签将为 B,或者只测试开始或结束,或者您可以取平均值。等等。所以我将展示如何检查一个特定的日期时间是否位于间隔。我不知道有哪个库比日期时间库更能自动化执行此任务。

日期时间库

import datetime

now = datetime.datetime.now()
hour = now.hour
# day of the week as int, where Mon 0 and Sun 6
day = now.weekday()

if day < 5 and hour >= 7 and hour < 19:
    label = "A"
else:
    label = "B"

print(label)
Run Code Online (Sandbox Code Playgroud)

您还可以检查小时或天是否在范围或列表中。例如,如果您想考虑在 12 点到 13 点之间休息:

if hour in range(7, 13) or hour in range(13, 19):
    # do something
Run Code Online (Sandbox Code Playgroud)

有关更多信息的文档:https://docs.python.org/3.8/library/datetime.html 人们也经常推荐 Pendulum 库,但通过滚动它的文档,我看不到任何比上述方法更容易完成任务的方法代码。当然你可以做这样的事情(但这对我来说似乎并不容易;代码没有经过测试):

使用摆的替代解决方案

import pendulum

now = pendulum.now()
daystart = now.start_of('day')
weekstart = now.start_of('week')

if now < weekstart.add(days=5) and now > daystart.add(hours=7) and now < daystart.add(hours=19):
    label = "A"
else:
    label = "B"
Run Code Online (Sandbox Code Playgroud)

摆文档: https: //pendulum.eustace.io/docs

在这里必须说明的是,这两种解决方案都可以在两个库(钟摆和日期时间)中以这种方式(或进行一些调整)完成,并且可能在我还没有提到的许多其他库中完成。

奖金

既然您要求一种更普遍地处理此类事情的方法,我将向您展示最后一件事如何使用第一个解决方案并使其更加通用:

import datetime

gethour = lambda dt : dt.hour
getday = lambda dt : dt.weekday()

timeframes = {
    "A": {
        getday: range(0,6),
        gethour: range(7,13) + range(13,19)
    },
    "break": {
        getday: range(0,6),
        gethour: [12]
    }
}
default = "B"

now = datetime.datetime.now()

for tag, timeframe in timeframes.items():
    label = tag
    for getter, limit in timeframe.items():
        if not getter(now) in limit:
            label = default
            break
    if label != default:
        break

print(label)
Run Code Online (Sandbox Code Playgroud)

  • 这(仍然)不是问题的答案。 (3认同)