Python列表中EC2实例日期对象经strftime格式化后排序异常
问题解决:EC2实例报表日期排序异常
问题根因
排序异常的核心原因是:直接对%b %d %Y格式的日期字符串做字典序排序,和实际日期先后逻辑不匹配。
比如字符串排序时,首字母靠前的Aug(8月)会排在Mar(3月)前面,和实际的时间先后完全不符,所以出现乱序。
修复方案
推荐优先用原始datetime对象排序,排完再格式化输出,避免字符串转换带来的排序误差,修改逻辑如下:
- 拼接列表时不要直接存格式化好的字符串,而是先存储包含原始附着时间的元组,保留datetime类型用于排序
- 基于原始datetime对象完成排序后,再格式化日期输出成你需要的格式
修改后参考代码
import datetime from datetime import timezone response = ec2_client.describe_instances( MaxResults=10 ) header_row = 'InstanceID, CreationDateTime, AutoScalingGroupName' + '\n' instances_list = [] max_age = 30 # 替换为你实际定义的max_age取值 for x in range(len(response['Reservations'])): # 获取实例ID instance_id = response['Reservations'][x]['Instances'][0]['InstanceId'] # 获取网卡附着时间 network_interface_id = response['Reservations'][x]['Instances'][0]['NetworkInterfaces'][0]['NetworkInterfaceId'] network_interface_details = ec2_client.describe_network_interfaces( NetworkInterfaceIds=[network_interface_id] ) attach_time = network_interface_details['NetworkInterfaces'][0]['Attachment']['AttachTime'] time_between_insertion = datetime.now(timezone.utc) - attach_time # 获取自动扩缩容组名称 tags = response['Reservations'][x]['Instances'][0]['Tags'] autoscaling_group_name = get_tag(tags, 'aws:autoscaling:groupName') if time_between_insertion.days > max_age: # 先存原始时间、实例ID、组名的元组,不提前格式化日期 instances_list.append( (attach_time, instance_id, autoscaling_group_name) ) # 直接用原始datetime对象排序,顺序完全准确 sorted_list = sorted(instances_list, key=lambda item: item[0]) # 排完序后再格式化日期输出 print(header_row) for item in sorted_list: attach_time, instance_id, asg_name = item # 按你需要的格式转字符串,比如原来的 Aug 05 2021 格式 formatted_date = attach_time.strftime("%b %d %Y") print(f"{instance_id},{formatted_date},{asg_name}")
如果你一定要提前格式化日期再排序,就把日期格式改成YYYY-MM-DD(比如2017-03-09),这种格式的字符串字典序和日期顺序是一致的,也可以得到正确结果。
内容的提问来源于stack exchange,提问作者devdude
相关产品推荐
相关产品推荐

