【问题标题】:parse dates with icalendar and compare to python datetime使用 icalendar 解析日期并与 python datetime 进行比较
【发布时间】:2019-01-28 17:26:12
【问题描述】:

我有一个 .ics 文件,我想从中提取今天发生的所有事件。我想我无法将 icalendar DTSTART 和 DTEND 转换为 python 日期时间。我尝试关注icalendar.readthedocs.org 的文档。我得到的列表是空的,不应该是这样。

这是我的代码:

import urllib2
import json
from datetime import datetime
from icalendar import Calendar, Event, vDatetime


def getTodayEvents(icsFile):
    cal = Calendar.from_ical(icsFile)
    today = datetime.now().date()
    entries = []
    for event in cal.walk('VEVENT'):
        dtstart = event['DTSTART']
        dtend = event['DTEND']
        start = vDatetime.from_ical(dtstart)      //Trouble here?
        end = vDatetime.from_ical(dtend)
        if start <= today <= end:
            entry = {'summary' : event['SUMMARY'] }
            entries.append(entry)
   output = json.dumps(entries)
   return output                                  //This list is empty

and ics 条目是这样的:

BEGIN:VEVENT
SUMMARY:Jonny Smith
DTSTART;VALUE=DATE:20140731
DTEND;VALUE=DATE:20150802
UID: 12345
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20141006T160145Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION:Mansfield\, GA
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-BUSYSTATUS:FREE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:TRUE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
END:VEVENT

【问题讨论】:

  • 好叫 JFS。谢谢。

标签: python datetime icalendar


【解决方案1】:

DTSTART、DTEND 属性有.dt 属性:

#!/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))

输出

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

【讨论】:

  • 这很重要,我希望在 iCalendar 文档中解释得更清楚
  • dt 有时返回 datetime.datetime 有时返回 datetime.date 对象吗?
  • @jhabbott:对于问题的输入,它返回date。不然我不知道
【解决方案2】:

event 对象有一个方法.decoded(),它为您提供datetime.date 对象(在您的情况下,.ics 只有一个日期)或datetime.datetime 对象。对于datetime.datetime 对象,还需要转换正确的时区。

为了统一比较,我把所有东西都转成字符串,然后再比较字符串。最后,我写了一个 isEventToday 方法:


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

代码对我来说看起来不太好,但它可以工作。

【讨论】:

    【解决方案3】:

    检查您的 if start &lt;= today &lt;= end: 比较中的数据类型或内容是否存在差异。看看(在调试器中)这三个变量的类型和内容是什么。我想您会发现比较是在比较合法比较的事物,但兼容性不足以给您期望的答案(即,此事件的开始和结束时间是否与今天的日期重叠?)

    您的today 是一个datetime 结构,可以按照您的意愿与其他datetimes 进行比较。也许您的vDatetime.from_ical(dtstart) 返回的不是datetime。快速浏览the source 看起来应该返回datetime。也许你有一个时区问题?查看所有三个的内容并检查哪个是&lt;==&gt; 其他。

    如果是这种情况,请将时区添加到您对 vDatetime.from_ical() 呼叫的呼叫中;

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

    您在.ics 中的时间表示Z - 即格林威治标准时间。

    如果您需要对日期进行更多操作,请参阅working with time

    【讨论】:

      猜你喜欢
      • 2013-07-20
      • 2020-02-21
      • 2011-06-04
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多