尽管使用普通的datetime python模块,您将能够实现所需的全部功能,但功能更强大的python-dateutil可用,尤其是在需要处理重复事件的情况下.下面的代码应向您指示如何实现目标:
from datetime import *
from dateutil.rrule import rrule, YEARLY
# GLOBAL CONFIG
td_8am = timedelta(seconds=3600*8)
td_jobfrequency = timedelta(seconds=3600) # hourly job
# USER DATA::
# birthday: assumed to be retrieved from some data source
bday = date(1960, 5, 12)
# reminder delta: number of days before the b-day
td_delta = timedelta(days=6)
# difference between the user TZ and the server TZ
tz_diff = timedelta(seconds=3600*5) # example: +5h
# from current time minus the job periodicity and the delta
sday = date.today()
# occr will return the first birthday from today on
occr = rrule(YEARLY, bymonth=bday.month, bymonthday=bday.day, dtstart=sday, count=1)[0]
# adjust: subtract the reminder delta, fixed 8h (8am) and tz difference
occr -= (td_delta + td_8am + tz_diff)
# send the reminder when the adjusted occurance is within this job time period
if datetime.now() - td_jobfrequency < occr < datetime.now():
print occr, '@todo: send the reminder'
else:
print occr, 'no reminder'
并且我建议您不要存储下一年的提醒日期,因为变化量可能会更改,或者时区可能会更改,甚至生日本身也会更改,因此您需要重新计算.上面的方法基本上是即时计算提醒日期(和时间).
我可以建议的另一件事是存储上次发送提醒的日期(包括年份在内的生日).因此,如果发生系统停机,您将不会错过提醒,而是发送所有尚未发送的提醒.您将需要修改代码以进行此附加检查和更新.