From 478785b415c48c4fda09c47c95d63ee86a0fba31 Mon Sep 17 00:00:00 2001 From: Elliott Jin Date: Sat, 25 Feb 2017 00:16:52 -0800 Subject: [PATCH] Google Calendar bot: Include time zone offsets in timestamps. Fixes: #3769 --- integrations/google/google-calendar | 32 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/integrations/google/google-calendar b/integrations/google/google-calendar index 47b541e..fc513a8 100755 --- a/integrations/google/google-calendar +++ b/integrations/google/google-calendar @@ -1,11 +1,16 @@ #!/usr/bin/env python +# +# This script depends on python-dateutil and python-pytz for properly handling +# times and time zones of calendar events. from __future__ import print_function import datetime +import dateutil.parser import httplib2 import itertools import logging import optparse import os +import pytz from six.moves import urllib import sys import time @@ -114,13 +119,26 @@ def get_events(): for event in feed["items"]: try: - start = event["start"]["dateTime"] + start = dateutil.parser.parse(event["start"]["dateTime"]) + # According to the API documentation, a time zone offset is required + # for start.dateTime unless a time zone is explicitly specified in + # start.timeZone. + if start.tzinfo is None: + event_timezone = pytz.timezone(event["start"]["timeZone"]) + # pytz timezones include an extra localize method that's not part + # of the tzinfo base class. + start = event_timezone.localize(start) # type: ignore except KeyError: - start = event["start"]["date"] - start = start[:19] - # All-day events can have only a date - fmt = '%Y-%m-%dT%H:%M:%S' if 'T' in start else '%Y-%m-%d' - start = datetime.datetime.strptime(start, fmt) + # All-day events can have only a date. + start_naive = dateutil.parser.parse(event["start"]["date"]) + + # All-day events don't have a time zone offset; instead, we use the + # time zone of the calendar. + calendar_timezone = pytz.timezone(feed["timeZone"]) + # pytz timezones include an extra localize method that's not part + # of the tzinfo base class. + start = calendar_timezone.localize(start_naive) # type: ignore + try: yield (event["id"], start, event["summary"]) except KeyError: @@ -133,7 +151,7 @@ def send_reminders(): messages = [] keys = set() - now = datetime.datetime.now() + now = datetime.datetime.now(tz=pytz.utc) for id, start, summary in events: dt = start - now