You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 13:42:02