Django虚拟环境下Python字符串分割索引越界问题求助
解决Django中分割谷歌日历时间字符串时的索引越界问题
这个问题我遇过不少次,根源在于你忽略了谷歌日历里全天事件和定时事件的格式差异——你看到的正常输出都是定时事件的结果,但代码运行时必然碰到了不带时分秒的全天事件,才触发了索引越界。
问题根源分析
当谷歌日历事件是全天事件时,API返回的end字段里只有date值(比如2024-05-20),而非带T的dateTime格式(比如2018-03-17T05:20:00+01:00)。
当你把这种纯日期字符串传给split_time函数的'time'参数时:
time_string.split('T')[-1]会返回整个日期字符串(因为没有T分隔符)split('+')[0]还是这个日期字符串(同样没有+分隔符)- 最后用
split(':')分割时,得到的是只有1个元素的列表(比如['2024-05-20']) - 这时候尝试访问
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
相关产品推荐
相关产品推荐

