parse dates with icalendar and compare to python datetime

吃可爱长大的小学妹 提交于 2019-12-06 16:35:29

DTSTART, DTEND properties have .dt attribute:

#!/usr/bin/env python
import json
from datetime import date
import icalendar # $ pip install icalendar

today = date.today()
calendar = icalendar.Calendar.from_ical(ics_file)
entries = [dict(summary=event['SUMMARY'])
           for event in calendar.walk('VEVENT')
           if event['DTSTART'].dt <= today <= event['DTEND'].dt]
print(json.dumps(entries, indent=2, sort_keys=True))

Output

[
  {
    "summary": "Jonny Smith"
  }
]

Check to see if you've got a discrepancy between data types or content in your if start <= today <= end: comparison. Take a look (in debugger or so) at what are the types and content of those three variables. I think you'll find that the comparison is comparing things that are legal to compare, but not compatible enough to give you the answer you expect (i.e., do the start and end times of this event overlap todays date?)

Your today is a datetime structure, which can be compared to other datetimes as you intend. Perhaps your vDatetime.from_ical(dtstart) is returning something other than a datetime. A quick glance at the source looks like it should be returning a datetime though. Maybe you've got a time zone issue? Look at the content of all three and check which is < or == or > others.

If that's the case, add a time zone to your calls to vDatetime.from_ical() calls;

start = vDatetime.from_ical(dtstart,'Europe/Amsterdam') #or wherever you are

Your time in the .ics indicates Z -- i.e., GMT.

If you need to do more with dates, see working with time.

The event object has a method .decoded(), which gives you either a datetime.date object (as in your case, the .ics only has a date) or a datetime.datetime object. For the datetime.datetime object, you additionally need to convert the correct timezone.

In order to make a unified comparison, I convert everything to a string and then compare the string. This ended up, that I wrote an isEventToday method:


from datetime import datetime, timezone, timedelta

def isEventToday(event):
    if event.get('dtstart') == None:
        dtstart = ""
    else:
        temp = event.decoded('dtstart')
        if isinstance(temp, datetime):
            dtstart = temp.astimezone().strftime("%Y-%m-%d")
        else:
            dtstart = temp.strftime("%Y-%m-%d")
    if event.get('dtend') == None:
        dtend = ""
    else:
        temp = event.decoded('dtend')
        if isinstance(temp, datetime):
            dtend = temp.astimezone().strftime("%Y-%m-%d")
        else:
            # dtend for day events is the day AFTER the event, so we
            # need to substract one!
            dtend = (temp - timedelta(days=1)).strftime("%Y-%m-%d")

    today = datetime.today().date().strftime("%Y-%m-%d")

    if dtstart != "" and dtstart == today:
        return True
    if dtend != "" and dtend == today:
        return True
    if dtstart != "" and dtend != "" and dtstart <= today and today <= dtend:
        return True
    return False

The code does not look nice to me, but it is working.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!