69_Python时间日期处理
Python时间日期处理:datetime库完全指南
文章目录
- Python时间日期处理:datetime库完全指南
- 前言
- 一、`datetime` 模块核心类
- 二、获取当前时间
- 三、创建指定日期时间
- 四、`strftime` 与 `strptime`:格式化与解析
- 4.1 `strftime`:日期时间 → 字符串
- 4.2 `strptime`:字符串 → 日期时间
- 4.3 格式化代码速查表
- 五、`timedelta`:日期计算
- 六、`time` 模块补充
- 七、实战案例
- 7.1 日期范围生成器
- 7.2 日志时间戳解析工具
- 7.3 简易倒计时器
- 7.4 工作日计算器
- 总结
- ✅ 亮点总结
- 适用场景
- 扩展方向
前言
时间日期处理是编程中最常见的需求之一——无论是记录日志时间戳、计算日期差、格式化输出,还是处理时区转换,都离不开时间和日期操作。Python提供了datetime、time和calendar三个核心模块来应对这些需求。
时间处理的常见坑:很多开发者在处理时间时踩过"时区"的坑——服务器在UTC时区,数据库存的是本地时间,前端又显示用户时区,三种时间混在一起调试时让人抓狂。此外,strftime和strptime的格式化代码容易混淆,闰年、月末、夏令时等边界条件也常常导致bug。本文将以datetime模块为主线,带你全面掌握Python时间日期处理的核心技巧,并特别强调那些容易出错的"暗坑"。
一、datetime模块核心类
datetime模块主要包含四个类:
fromdatetimeimportdate,time,datetime,timedelta# 1. date:只包含日期(年、月、日)d=date(2024,1,15)print(f"date:{d}")# 2024-01-15# 2. time:只包含时间(时、分、秒、微秒)t=time(14,30,45,500000)print(f"time:{t}")# 14:30:45.500000# 3. datetime:日期 + 时间dt=datetime(2024,1,15,14,30,45)print(f"datetime:{dt}")# 2024-01-15 14:30:45# 4. timedelta:时间间隔(两个日期/时间之间的差值)delta=timedelta(days=7,hours=3,minutes=30)print(f"timedelta:{delta}")# 7 days, 3:30:00二、获取当前时间
fromdatetimeimportdatetime,date,time# 当前日期时间now=datetime.now()print(f"当前日期时间:{now}")# 当前日期today=date.today()print(f"当前日期:{today}")# UTC时间(世界协调时)utc_now=datetime.utcnow()print(f"UTC时间:{utc_now}")# 获取年月日时分秒等属性print(f"年:{now.year}, 月:{now.month}, 日:{now.day}")print(f"时:{now.hour}, 分:{now.minute}, 秒:{now.second}")print(f"微秒:{now.microsecond}")print(f"星期几 (0=周一):{now.weekday()}")print(f"星期几 (1=周日):{now.isoweekday()}")三、创建指定日期时间
fromdatetimeimportdatetime,date,time# 直接构造dt1=datetime(2025,6,1,9,0,0)print(dt1)# 2025-06-01 09:00:00# 只提供日期部分dt2=datetime(2025,12,31)print(dt2)# 2025-12-31 00:00:00# 从时间戳创建timestamp=1705315200# 2024-01-15 12:00:00 UTCdt3=datetime.fromtimestamp(timestamp)print(f"从时间戳:{dt3}")# 从ISO格式字符串创建dt4=datetime.fromisoformat("2024-06-15T09:30:00")print(f"从ISO格式:{dt4}")# 合并date和timed=date(2025,1,1)t=time(12,30,0)dt5=datetime.combine(d,t)print(f"合并:{dt5}")# 2025-01-01 12:30:00四、strftime与strptime:格式化与解析
这是实际开发中使用频率最高的两个方法。两者的方向相反:strftime(format time)将datetime对象转换为字符串;strptime(parse time)将字符串解析为datetime对象。记住它们的区别有一个简单方法:f代表 format(格式化输出),p代表 parse(解析输入)。
4.1strftime:日期时间 → 字符串
fromdatetimeimportdatetime now=datetime.now()# 常用格式print(now.strftime("%Y-%m-%d"))# 2024-01-15print(now.strftime("%Y年%m月%d日"))# 2024年01月15日print(now.strftime("%Y/%m/%d %H:%M:%S"))# 2024/01/15 14:30:45print(now.strftime("%Y-%m-%d %I:%M %p"))# 2024-01-15 02:30 PMprint(now.strftime("%A, %B %d, %Y"))# Monday, January 15, 2024print(now.strftime("%j"))# 015 (一年中的第几天)print(now.strftime("%U"))# 03 (一年中的第几周)4.2strptime:字符串 → 日期时间
fromdatetimeimportdatetime# 解析各种格式的日期字符串date_str1="2024-01-15"dt1=datetime.strptime(date_str1,"%Y-%m-%d")print(dt1)# 2024-01-15 00:00:00date_str2="2024年01月15日 14:30:45"dt2=datetime.strptime(date_str2,"%Y年%m月%d日 %H:%M:%S")print(dt2)# 2024-01-15 14:30:45date_str3="15/Jan/2024:14:30:45"dt3=datetime.strptime(date_str3,"%d/%b/%Y:%H:%M:%S")print(dt3)# 2024-01-15 14:30:45# 解析中文日期date_str4="2024年1月15日"dt4=datetime.strptime(date_str4,"%Y年%m月%d日")print(dt4)4.3 格式化代码速查表
| 代码 | 含义 | 示例 |
|---|---|---|
%Y | 4位年份 | 2024 |
%m | 月份 (01-12) | 01 |
%d | 日期 (01-31) | 15 |
%H | 24小时 (00-23) | 14 |
%I | 12小时 (01-12) | 02 |
%M | 分钟 (00-59) | 30 |
%S | 秒 (00-59) | 45 |
%p | AM/PM | PM |
%A | 完整星期名 | Monday |
%B | 完整月份名 | January |
%j | 一年中第几天 | 015 |
五、timedelta:日期计算
timedelta是日期运算的核心工具,它表示两个日期/时间之间的差值。你可以用它对日期进行加减操作,也可以计算两个日期之间的间隔。常见陷阱:timedelta只支持 days、seconds 和 microseconds,不支持 months 和 years——因为月份和年份的长度不是固定的(28-31天,365/366天)。如果需要按月或按年进行计算,推荐使用第三方库dateutil的relativedelta。
fromdatetimeimportdatetime,timedelta now=datetime.now()# 日期加减tomorrow=now+timedelta(days=1)yesterday=now-timedelta(days=1)next_week=now+timedelta(weeks=1)three_hours_later=now+timedelta(hours=3)half_hour_ago=now-timedelta(minutes=30)print(f"明天:{tomorrow.strftime('%Y-%m-%d')}")print(f"昨天:{yesterday.strftime('%Y-%m-%d')}")print(f"下周:{next_week.strftime('%Y-%m-%d')}")print(f"3小时后:{three_hours_later.strftime('%H:%M')}")print(f"半小时前:{half_hour_ago.strftime('%H:%M')}")# 计算两个日期的差值birthday=datetime(1995,8,22)age_delta=now-birthdayprint(f"自出生已过:{age_delta.days}天")print(f"约{age_delta.days//365}年")# 计算项目截止时间deadline=datetime(2024,12,31,23,59,59)remaining=deadline-nowprint(f"距离截止还有:{remaining.days}天{remaining.seconds//3600}小时")六、time模块补充
time模块提供更底层的操作,主要处理时间戳和程序休眠。time和datetime的分工是:time模块处理底层的时间戳和系统时钟操作,datetime模块提供高级的面向对象的日期时间接口。在实际开发中,你可以根据需求灵活选择:需要处理人类可读的日期和时间时用datetime,需要操作时间戳或高精度计时时用time。
importtime# 当前时间戳(自1970-01-01以来的秒数)timestamp=time.time()print(f"当前时间戳:{timestamp}")# 休眠print("等待3秒...")time.sleep(3)print("继续执行!")# 时间戳 ↔ 结构化时间local_time=time.localtime(timestamp)print(f"本地时间:{time.strftime('%Y-%m-%d %H:%M:%S',local_time)}")# UTC结构化时间utc_time=time.gmtime(timestamp)print(f"UTC时间:{time.strftime('%Y-%m-%d %H:%M:%S',utc_time)}")# 结构化时间 → 时间戳new_timestamp=time.mktime(local_time)print(f"转回时间戳:{new_timestamp}")# 性能计时(高精度)start=time.perf_counter()result=sum(range(1000000))end=time.perf_counter()print(f"计算耗时:{end-start:.6f}秒")七、实战案例
理论知识最终要落地到实际场景。以下四个案例覆盖了时间日期处理最常见的工作场景——日期范围生成、日志时间戳解析、倒计时器和工作日计算。每个案例都可以作为模板代码直接使用。
7.1 日期范围生成器
fromdatetimeimportdatetime,timedeltadefdate_range(start_date,end_date):"""生成两个日期之间的所有日期"""current=start_datewhilecurrent<=end_date:yieldcurrent current+=timedelta(days=1)# 生成某月所有日期start=datetime(2024,1,1)end=datetime(2024,1,31)fordindate_range(start,end):ifd.weekday()<5:# 仅工作日weekday_name=["周一","周二","周三","周四","周五","周六","周日"]print(f"{d.strftime('%Y-%m-%d')}{weekday_name[d.weekday()]}")7.2 日志时间戳解析工具
fromdatetimeimportdatetimeimportre LOG_PATTERNS=[# 常见日志格式r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}",# 2024-01-15 14:30:45r"\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2}",# 15/Jan/2024:14:30:45r"\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}",# 2024/01/15 14:30:45]defparse_log_timestamp(line):"""尝试多种格式解析日志中的时间戳"""forpatterninLOG_PATTERNS:match=re.search(pattern,line)ifmatch:ts_str=match.group()# 尝试多种格式forfmtin["%Y-%m-%d %H:%M:%S","%d/%b/%Y:%H:%M:%S","%Y/%m/%d %H:%M:%S",]:try:returndatetime.strptime(ts_str,fmt)exceptValueError:continuereturnNone# 测试log_lines=['2024-01-15 14:30:45 INFO Server started','15/Jan/2024:14:31:20 ERROR Connection refused','2024/01/15 14:32:00 WARN Disk usage 90%',]forlineinlog_lines:ts=parse_log_timestamp(line)ifts:print(f"{ts}->{line}")7.3 简易倒计时器
fromdatetimeimportdatetime,timedeltaimporttimedefcountdown(target_desc,target_datetime):"""显示活动倒计时"""whileTrue:now=datetime.now()remaining=target_datetime-nowifremaining.total_seconds()<=0:print(f"\r{target_desc}已到来!"+" "*20)breakdays=remaining.days hours,remainder=divmod(remaining.seconds,3600)minutes,seconds=divmod(remainder,60)display=f"\r距离{target_desc}还有:{days}天{hours:02d}时{minutes:02d}分{seconds:02d}秒"print(display,end="",flush=True)time.sleep(1)print()# 使用示例(设置一个未来时间点)# target = datetime(2025, 1, 1, 0, 0, 0)# countdown("2025年元旦", target)print("倒计时器已就绪(取消注释上方代码运行)")7.4 工作日计算器
fromdatetimeimportdatetime,timedeltadefadd_business_days(start_date,days):"""在start_date基础上增加days个工作日"""current=start_date remaining=dayswhileremaining>0:current+=timedelta(days=1)# weekday(): 0=周一, 6=周日ifcurrent.weekday()<5:# 周一至周五remaining-=1returncurrentdefbusiness_days_between(start,end):"""计算两个日期之间的工作日天数"""current=start count=0whilecurrent<=end:ifcurrent.weekday()<5:count+=1current+=timedelta(days=1)returncount# 使用示例today=datetime.now().replace(hour=0,minute=0,second=0,microsecond=0)deadline=add_business_days(today,10)print(f"今天:{today.strftime('%Y-%m-%d')}")print(f"10个工作日后:{deadline.strftime('%Y-%m-%d')}")start=datetime(2024,1,1)end=datetime(2024,1,31)working_days=business_days_between(start,end)print(f"2024年1月工作日:{working_days}天")总结
Python时间日期处理的核心要点:
| 需求 | 推荐方案 |
|---|---|
| 获取当前时间 | datetime.now() |
| 格式化输出 | 使用strftime() |
| 解析日期字符串 | 使用strptime() |
| 日期加减计算 | 使用timedelta |
| 时间戳处理 | 使用time.time()/datetime.fromtimestamp() |
| 程序休眠 | 使用time.sleep() |
| 高精度计时 | 使用time.perf_counter() |
掌握datetime模块能让你轻松应对90%以上的时间日期处理需求。下一篇我们将学习数据序列化(JSON与Pickle),看看如何持久化和传输Python对象。
✅ 亮点总结
- 清晰梳理
date、time、datetime、timedelta四大核心类的职责与关系 strftime()与strptime()的格式化速查表,覆盖日期时间字符串的转换全场景- 时间戳(timestamp)与时区(timezone)处理,解决跨时区应用的常见问题
- 实战案例:工作日计算器,演示 timedelta 累计、日期范围判断、节假日排除
适用场景
- 日志系统:为每条日志添加高精度时间戳,用于问题追踪和性能分析
- 定时任务:计算下一次执行的精确时间,如每日报表生成、定时数据清理
- 业务系统:计算合同期限、会员有效期、倒计时等时间相关的业务逻辑
扩展方向
- 学习
dateutil第三方库,支持更灵活的日期解析(如"下周三"、"3天后"等自然语言) - 探索
pytz库处理全球时区,结合datetime实现真正的跨时区时间计算 - 掌握
arrow/pendulum等新一代时间库,获得更人性化的 API 体验