Google calendar API 설명문서에는 event list를 가져오는 방법이 설명과 함께 예제 code가 제시되어 있다.
page_token = None while True: events = service.events().list(calendarId='primary', pageToken=page_token).execute() for event in events['items']: print event['summary'] page_token = events.get('nextPageToken') if not page_token: break
이 코드를 수행하면 달력이 가지고 있는 모든 event들을 가져오는데, 이것을 조금 수정해서 지정된 달에 해당하는 event 목록을 가져오는 것으로 변경해 보자.
timeMax / timeMin
가져올 event의 범위는 lower bound를 나타내는 timeMin과 upper bound를 나타내는 timeMax값으로 제한할 수 있는데 이때 사용되는 날짜의 형식은 RFC3339을 따라야 한다.
calendar.monthrange()
이 method는 년도와 월을 받아서 시작일의 주와 마지막 날짜를 tuple로 반환해 준다. 다음과 같이 특정 달의 마지막 날짜를 구할 수 있다.
>>> import calendar >>> calendar.monthrange(2002, 06) (5, 30) >>> calendar.monthrange(2002, 06)[1] 30
Python에서 RFC3339 표시하기
이 형식은 간단히 말해 날짜를 나타내는 YYYY-MM-DD 형식과 시간을 나타내는 hh:mm:ss가 대문자 ‘T’로 연결되며 그 뒤에는 UTC로 부터의 time zone offset값이 붙는다.
2002-06-30T20:00:00+09:00
datetime.isoformat()을 이용하면 비슷한 형식을 얻을 수는 있으나, 뒤에 붙는 time zone offset이 표시되지 않는다.
>>> datetime(2002, 06, 30, 20, 0, 0).isoformat() '2002-06-30T20:00:00'
Python에서 time zone을 나타내는 tzinfo class의 설명문에 따르면 tzinfo는 abstract class여서 직접 사용할 수 없고, 이를 상속받는 class를 구현해서 사용해야 한다. 다음은 이 문서에 있는 예제를 조금 수정하여 time zone offset 값을 반환하는 tzinfo의 concrete class를 구현한 것이다.
from datetime import tzinfo, timedelta, datetime ZERO = timedelta(0) HOUR = timedelta(hours=1) class TimeZoneOffset(tzinfo): def __init__(self, hours, name): self.__offset = timedelta(hours = hours) self.__name = name def utcoffset(self, dt): return self.__offset def tzname(self, dt): return self.__name def dst(self, dt): return ZERO
Code
TimeZoneOffset class를 선언한 후에는 datetime()을 호출할때 tzinfo에 TimeZoneOffset의 instance를 넘겨서 time zone offset 정보를 포함하는 RFC3339 날짜 형식을 얻을 수 있다.
# What's the last date of the Jun, 2002? lastDate = calendar.monthrange(2002, 6)[1] # Lower bound RFC3339 format '2002-06-01T00:00:00+09:00' lbound = datetime(2002, 6, 1, tzinfo=TimeZoneOffset(9, "KST")).isoformat() # Lower bound RFC3339 format '2002-06-01T23:59:59+09:00' ubound = datetime(2002, 6, lastDate, 23, 59, 59, tzinfo=TimeZoneOffset(9, "KST")).isoformat() page_token = None while True: # Fetch events within given lower/upper bounds. events = service.events().list(calendarId='primary', minTime=lbound, maxTime=ubound, pageToken=page_token).execute() for event in events['items']: print event['summary'] page_token = events.get('nextPageToken') if not page_token: break