Python调用Google Calendar API时区与时间偏移问题求解
问题解决方法
问题核心原因
- 你当前代码的错误根源是直接对格式不同的时间字符串做比较,没有转成统一时区的datetime对象计算:
你测试时本地是BST(UTC+1)20:31,代码中now取的是UTC时间19:31对应的字符串2021-07-16T19:31:xxZ,而接口返回的会议开始时间是带英国时区偏移的字符串2021-07-16T20:00:00+01:00,字符串逐字符比较时19点的字符串小于20点的字符串,就会误判会议未开始。 - 另外你用
datetime.utcnow()生成的是无时区信息的原生datetime对象,和带时区偏移的时间做计算很容易出问题。
修改方案
所有时间逻辑统一用Europe/London时区的带偏移datetime对象处理,不要直接比较时间字符串。
前置依赖
Python 3.9+版本自带zoneinfo模块可以直接用,如果是旧版本Python,先执行pip install pytz,替换代码中的时区导入部分即可。
修改后完整代码
from datetime import datetime, timedelta, timezone from zoneinfo import ZoneInfo # 旧版本Python替换为 import pytz service = build('calendar', 'v3', credentials=creds) # 定义英国时区 UK_TZ = ZoneInfo("Europe/London") # 旧版本Python替换为 UK_TZ = pytz.timezone("Europe/London") # 1. 取当前英国时区的时间,同时保留UTC时间用于API请求 utc_now = datetime.now(timezone.utc) uk_now = datetime.now(UK_TZ) utc_12 = utc_now + timedelta(hours=12) # 2. API请求部分不变,仍然传UTC时间就行,谷歌会根据指定timeZone返回正确格式的时间 now = utc_now.isoformat().replace("+00:00", "Z") now12 = utc_12.isoformat().replace("+00:00", "Z") events_result = service.events().list( calendarId='###############@resource.calendar.google.com', timeZone="Europe/London", timeMin=now, maxResults=1, singleEvents=True, showDeleted=False, timeMax=now12, orderBy='startTime' ).execute() events = events_result.get('items', []) if not events: print('meetingStart="NoEvents"') for event in events: startTime_str = event['start'].get('dateTime') endTime_str = event['end'].get('dateTime') eventTitle=event['summary'] eventOrganizer=event['creator'].get('email') try: eventConferencing=event['conferenceData'].get('conferenceSolution').get('name') except: eventConferencing=(' ') # 3. 把接口返回的时间字符串转成英国时区的datetime对象再比较 startTime = datetime.fromisoformat(startTime_str) endTime = datetime.fromisoformat(endTime_str) if startTime <= uk_now <= endTime: inProgress=('true') else: inProgress=('false') safeEventTitle= "" for i in eventTitle: num = ord(i) if 0 <= num <=127: safeEventTitle= safeEventTitle + i print('meetingStart="' + startTime_str + '"') print('meetingEnd="' + endTime_str + '"') print('meetingTitle="' + safeEventTitle + '"') print('meetingOrganizer="' + eventOrganizer + '"') print('meetingConferencing="' + eventConferencing + '"') print('meetingInProgress="' + inProgress + '"')
验证说明
修改后你测试时的uk_now会是带+01:00偏移的2021-07-16T20:31:xx+01:00,和会议的起止时间对象比较时,会正确命中20:00 <= 20:31 <=21:00的条件,meetingInProgress会返回正确的true。
内容的提问来源于stack exchange,提问作者marty.p
相关产品推荐
相关产品推荐

