Сортировка запланированных событий Python

Итак, у меня есть список событий, похожих на сигналы тревоги. Они определяются временем начала и окончания (в часах и минутах), диапазоном дней (т.е. 1-3, с воскресенья по среду) и диапазоном месяцев (т.е. с 1-3, с января по март). Формат этих данных практически неизменен. Мне нужно не обязательно сортировать список, но мне нужно найти следующее предстоящее событие на основе текущего времени. Есть так много разных способов сделать это и так много разных угловых случаев. Это мой псевдокод:



now = time()
diff = []
# Start difference between now and start times
for s in schedule #assuming appending to diff
    diff.minutes = s.minutes - time.minutes #
    diff.hours = s.hours - time.hours
    diff.days = s.days - time.days
    diff.months = s.months - time.months

for d in diff
    if d < 0
        d = period + d 
        # period is the maximum period of the attribute. ie minutes is 60, hours is 24

# repeat for event end times


Итак, теперь у меня есть список кортежей разностей в часах, минутах, днях и неделях. Этот кортеж уже учитывает, прошло ли время начала, но до времени окончания. Допустим, сейчас август, месяц начала мероприятия — июль, а месяц окончания — сентябрь, так что diff.month == 0.

Теперь этот конкретный угловой случай доставляет мне проблемы:

Допустим, расписание работает с 0 до 23:59 по четвергам в августе. И это пятница 27-е. При запуске моего алгоритма разница в месяцах будет равна 0, тогда как на самом деле он не будет работать снова до следующего августа, поэтому должно быть 12. И я застрял. Месяц - единственная проблема, я думаю, потому что месяц - это единственный атрибут, который напрямую зависит от даты конкретного месяца (а не только от дня). В порядке ли мой алгоритм, и я могу просто справиться с этим особым случаем? Или есть что-то лучше для этого?

Это данные, с которыми я работаю

    map['start_time']=''
    map['end_time']=''
    map['start_moy']='' 
    map['end_moy']='' 
    map['start_dow']=''      
    map['end_dow']=''

Метод getAllSchedules расписания просто возвращает список всех расписаний. Я могу изменить класс расписания, но я не уверен, что это может изменить. Я не могу добавить/изменить формат предоставленных мне расписаний


person Falmarri    schedule 12.08.2010    source источник
comment
Батареи включены. Используйте математику даты и времени. docs.python.org/library/datetime.html   -  person msw    schedule 13.08.2010


Ответы (4)


Преобразуйте элементы из расписания в объекты datetime. Затем вы можете просто отсортировать их

from datetime import datetime
events = sorted(datetime(s.year, s.month, s.day, s.hour, s.minute) for s in schedule)
person John La Rooy    schedule 12.08.2010
comment
Проблема в том, что запланированное событие не имеет фактической даты, связанной с ним, только четверги в августе. Если бы я мог преобразовать дату и время, это было бы неплохо, но без фактической даты мне все равно пришлось бы решать проблему, с которой я сейчас столкнулся. - person Falmarri; 13.08.2010
comment
@Falmarri, все же лучше использовать модуль datetime, так как он позаботится о ваших крайних случаях. Можете ли вы дать код для вашего расписания занятий? - person John La Rooy; 13.08.2010
comment
У меня также нет атрибута года - person Falmarri; 13.08.2010
comment
@Falmarri, возможно, вы можете заменить datetime.now().year, если год не имеет значения. Я не могу сказать наверняка, пока не увижу расписание занятий - person John La Rooy; 13.08.2010
comment
Я, вероятно, не должен публиковать фактический код. Вы имеете в виду мой класс расписания, который я звоню выше? Все, что он возвращает, - это карта информации, которую я уже дал, это просто класс Parser, возвращающий карту для каждого из событий. Я опубликую фактические поля в своем вопросе. Если вы говорите о планировщике, который будет работать и запрашивать у меня время, я понятия не имею, как это будет реализовано. - person Falmarri; 13.08.2010

Поскольку ваше разрешение указано в минутах и ​​при условии, что у вас не так много событий, я бы просто сканировал все события каждую минуту.

Отфильтруйте свои события, чтобы у вас был новый список, в котором диапазон событий соответствует текущему месяцу и дню.

Затем для каждого из этих событий объявите, что они активны или неактивны в зависимости от того, соответствует ли текущее время диапазону события.

person quamrana    schedule 12.08.2010
comment
Я не могу контролировать, как часто запускается планировщик. Все, что мне нужно сделать, это дать ему следующее запланированное событие, когда оно попросит меня - person Falmarri; 13.08.2010

Основная проблема, по-видимому, связана с тем, что вы используете день недели вместо явных дней месяца.

Хотя приведенный вами крайний случай является одним из примеров, не возникает ли эта проблема со всеми событиями, запланированными на любой месяц, кроме текущего?

Я думаю, что наиболее надежным подходом здесь было бы выполнить работу по преобразованию запланированных событий в формат даты и времени, а затем использовать предложение @gnibbler по сортировке объектов даты и времени.

Как только вы определили, что последнее событие текущего месяца уже прошло, рассчитайте расстояние до следующего месяца, в котором произошло событие (будь то + 1 год или просто + 1 месяц), а затем создайте объект datetime с этой информацией:

first_of_month = datetime.date(calculated_year, calculated_month, 1)

Используя первый день месяца, вы можете использовать:

day_of_week = first_of_month.strftime('%w')

Чтобы дать вам, на какой день недели приходится первый день этого месяца, который вы затем можете использовать для расчета, сколько дней добавить, чтобы получить первый, второй, третий и т. д. экземпляр данного дня недели, для в том месяце. Как только у вас будет этот день, вы можете создать действительный объект datetime и делать любые сравнения, которые вы хотите, с now().

person Andrew    schedule 12.08.2010
comment
Это более или менее то, что делает мой алгоритм выше. Тем не менее, это все еще упускает из виду краеугольный случай, когда в месяце больше нет определенного дня. - person Falmarri; 13.08.2010
comment
Отредактировал мое решение исключительно для крайних случаев. - person Andrew; 13.08.2010

Я не мог понять, как это сделать, используя только дату и время. Но я нашел модуль и использовал это. Идеально

http://labix.org/python-dateutil

person Falmarri    schedule 13.08.2010