Python 3比较EC2实例datetime与本地datetime的TypeError问题及解决
解决AWS EC2实例时间比较的时区类型不匹配问题
你碰到的这个TypeError: can't compare offset-naive and offset-aware datetimes问题,原因很直白:
- AWS EC2 API返回的
launchTime是**带时区偏移(offset-aware)**的datetime对象(默认带UTC时区信息) - 而
datetime.datetime.now()生成的是**无时区信息(offset-naive)**的本地时间对象
Python不允许直接比较这两种不同类型的datetime,必须先统一它们的类型才能进行判断。
快速修复方案
最简单的处理方式是用replace(tzinfo=None)移除launchTime的时区信息,把它转换成和datetime.now()同类型的无时区datetime,这样就能正常做时间比较了:
错误代码
if launchTime < datetime.datetime.now()-datetime.timedelta(seconds=20):
修正后代码
if launchTime.replace(tzinfo=None) < datetime.datetime.now()-datetime.timedelta(minutes=4):
完整Lambda函数代码(自动停止运行超指定时长的EC2实例)
下面是完整的Python 3代码,这个Lambda函数由CloudWatch每4分钟触发一次,会自动停止运行超过5分钟的EC2实例(示例中判断逻辑设为运行超4分钟就触发停止,结合触发间隔,实际会停止运行满5分钟的实例):
import boto3 import datetime # 初始化EC2客户端 client = boto3.client('ec2') def lambda_handler(event, context): # 获取所有EC2实例信息 response = client.describe_instances() # 遍历所有实例 reservation 和实例本身 for r in response['Reservations']: for i in r['Instances']: # 仅处理处于运行状态的实例 if i["State"]["Name"] == "running": launch_time = i["LaunchTime"] # 判断实例运行时长是否超过设定阈值(此处为4分钟) if launch_time.replace(tzinfo=None) < datetime.datetime.now() - datetime.timedelta(minutes=4): # 执行停止实例操作 stop_response = client.stop_instances( InstanceIds=[i["InstanceId"]] ) print(f"已成功停止实例: {i['InstanceId']}")
内容的提问来源于stack exchange,提问作者jelidens
相关产品推荐
相关产品推荐

