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

Django虚拟环境下Python字符串分割索引越界问题求助

解决Django中分割谷歌日历时间字符串时的索引越界问题

这个问题我遇过不少次,根源在于你忽略了谷歌日历里全天事件和定时事件的格式差异——你看到的正常输出都是定时事件的结果,但代码运行时必然碰到了不带时分秒的全天事件,才触发了索引越界。

问题根源分析

当谷歌日历事件是全天事件时,API返回的end字段里只有date值(比如2024-05-20),而非带T的dateTime格式(比如2018-03-17T05:20:00+01:00)。

当你把这种纯日期字符串传给split_time函数的'time'参数时:

  1. time_string.split('T')[-1]会返回整个日期字符串(因为没有T分隔符)
  2. split('+')[0]还是这个日期字符串(同样没有+分隔符)
  3. 最后用split(':')分割时,得到的是只有1个元素的列表(比如['2024-05-20'])
  4. 这时候尝试访问test[1]自然会触发list index out of range错误。

解决方案:分两步处理

1. 优化split_time函数,兼容纯日期格式

先增加格式校验,处理没有T的纯日期字符串:

def split_time(time_string, string):
    # 先判断是否为带时间的ISO格式(包含T)
    if 'T' not in time_string:
        if string == 'date':
            return time_string
        elif string == 'time':
            # 全天事件默认返回00:00:00,也可以返回None后续处理
            return '00:00:00'
    
    if string == 'date':
        return time_string.split('T')[0]
    elif string == 'time':
        pre_time = time_string.split('T')[-1]
        return pre_time.split('+')[0]

2. 在业务函数中过滤全天事件,增加索引安全检查

在处理事件前,先判断是否为带dateTime的定时事件,同时在分割时间后增加长度校验:

def is_double(start_date, start_time, end_date, end_time):
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('calendar', 'v3', http=http)
    
    start_date_time = start_date +'T'+ start_time +":00+02:00"
    print("testing:", start_date_time )
    end_date_time = end_date +'T'+ end_time +":00+02:00"
    
    start_now = datetime.datetime.utcnow().isoformat() + 'Z'
    eventsResult = service.events().list(
        calendarId='primary',
        timeMin=start_now,
        maxResults=20,
        singleEvents=True,
        orderBy='startTime'
    ).execute()
    events = eventsResult.get('items', [])
    
    if not events:
        print('no event')
        return False
    
    for event in events:
        # 区分全天事件和定时事件
        if 'dateTime' not in event['end']:
            print(f"Skipping all-day event: {event.get('summary', 'Unnamed Event')}")
            continue
            
        end = event['end']['dateTime']
        end_event_time = split_time(end, 'time')
        test = end_event_time.split(':')
        
        # 增加安全检查,防止意外格式
        if len(test) < 3:
            print(f"Unexpected time format: {end_event_time}")
            continue
            
        h = test[0]
        m = test[1]  # 现在这里不会再触发索引越界
        s = test[2]
        print(end_event_time, test, h, m, s)
    
    return True  # 注意Python里布尔值首字母大写:True,不是true

额外提示

  • 原代码里的return true是语法错误,Python布尔值必须大写为True
  • 如果需要处理全天事件的时间逻辑,可以根据业务需求修改split_time函数的返回值(比如返回None后单独处理)

内容的提问来源于stack exchange,提问作者ItsMeTheBee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:33:40