Разделите интервал между датой и временем в соответствии с помеченным разделом недели - PullRequest
0 голосов
/ 27 октября 2019

У меня есть shift, который является интервалом даты и времени (пара datetime с). Мои недели имеют помеченный раздел (каждая неделя одна и та же: разделена на части, а каждая часть имеет ярлык). Я хочу разделить shift на помеченные части (т.е. на несколько подинтервалов) в соответствии с разделением недели.

Пример. Предположим, shift - это интервал 2019-10-21 18:30- 2019-10-22 08:00, а раздел недели выглядит следующим образом: с понедельника по пятницу с 07:00 до 19:00 - метка A, а на остальной части недели - метка 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.

Как это вообще сделать?

Ввод: a datetime интервал (пара) и помеченный раздел недели (как лучше всего это представить?)

Вывод: списокпомеченных datetime интервалов (пар).

1 Ответ

0 голосов
/ 29 октября 2019

Вы не определили, что произойдет, если один из ваших лимитов смены (начало или конец) лежит в пределах одной части вашей недели, а другой - вне. Например, что произойдет, если у вас есть

2019-10-21 18:30 - 2019-10-21 19:00

Это A или B? Вы можете либо создать правила, согласно которым, если одна часть находится в «B», метка будет B, либо просто проверить начало или конец, либо вы можете взять среднее значение и т. Д. Поэтому я покажу, как проверить, лежит ли одна конкретная дата-время внутриинтервалы. Я не знаю, какая библиотека автоматизировала эту задачу больше, чем библиотека datetime.

библиотека datetime

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)

Вы также можете проверить, лежит ли час или день вдиапазон или список. Например, если вы хотите рассмотреть перерыв между 12 и 13 часами:

if hour in range(7, 13) or hour in range(13, 19):
    # do something

документы для получения дополнительной информации: https://docs.python.org/3.8/library/datetime.html Люди также часто рекомендуют библиотеку маятника, но, просматривая ее документыЯ не вижу ни одного метода, который облегчает вашу задачу, чем приведенный выше код. Конечно, вы могли бы сделать что-то подобное (но мне кажется, что это не так просто; код не тестируется):

альтернативное решение с использованием маятника

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"

документация маятника: 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)
...