发布时间:2026/7/2 20:00:39
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只包含日期年、月、日ddate(2024,1,15)print(fdate:{d})# 2024-01-15# 2. time只包含时间时、分、秒、微秒ttime(14,30,45,500000)print(ftime:{t})# 14:30:45.500000# 3. datetime日期 时间dtdatetime(2024,1,15,14,30,45)print(fdatetime:{dt})# 2024-01-15 14:30:45# 4. timedelta时间间隔两个日期/时间之间的差值deltatimedelta(days7,hours3,minutes30)print(ftimedelta:{delta})# 7 days, 3:30:00二、获取当前时间fromdatetimeimportdatetime,date,time# 当前日期时间nowdatetime.now()print(f当前日期时间:{now})# 当前日期todaydate.today()print(f当前日期:{today})# UTC时间世界协调时utc_nowdatetime.utcnow()print(fUTC时间:{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# 直接构造dt1datetime(2025,6,1,9,0,0)print(dt1)# 2025-06-01 09:00:00# 只提供日期部分dt2datetime(2025,12,31)print(dt2)# 2025-12-31 00:00:00# 从时间戳创建timestamp1705315200# 2024-01-15 12:00:00 UTCdt3datetime.fromtimestamp(timestamp)print(f从时间戳:{dt3})# 从ISO格式字符串创建dt4datetime.fromisoformat(2024-06-15T09:30:00)print(f从ISO格式:{dt4})# 合并date和timeddate(2025,1,1)ttime(12,30,0)dt5datetime.combine(d,t)print(f合并:{dt5})# 2025-01-01 12:30:00四、strftime与strptime格式化与解析这是实际开发中使用频率最高的两个方法。两者的方向相反strftimeformat time将datetime对象转换为字符串strptimeparse time将字符串解析为datetime对象。记住它们的区别有一个简单方法f代表 format格式化输出p代表 parse解析输入。4.1strftime日期时间 → 字符串fromdatetimeimportdatetime nowdatetime.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_str12024-01-15dt1datetime.strptime(date_str1,%Y-%m-%d)print(dt1)# 2024-01-15 00:00:00date_str22024年01月15日 14:30:45dt2datetime.strptime(date_str2,%Y年%m月%d日 %H:%M:%S)print(dt2)# 2024-01-15 14:30:45date_str315/Jan/2024:14:30:45dt3datetime.strptime(date_str3,%d/%b/%Y:%H:%M:%S)print(dt3)# 2024-01-15 14:30:45# 解析中文日期date_str42024年1月15日dt4datetime.strptime(date_str4,%Y年%m月%d日)print(dt4)4.3 格式化代码速查表代码含义示例%Y4位年份2024%m月份 (01-12)01%d日期 (01-31)15%H24小时 (00-23)14%I12小时 (01-12)02%M分钟 (00-59)30%S秒 (00-59)45%pAM/PMPM%A完整星期名Monday%B完整月份名January%j一年中第几天015五、timedelta日期计算timedelta是日期运算的核心工具它表示两个日期/时间之间的差值。你可以用它对日期进行加减操作也可以计算两个日期之间的间隔。常见陷阱timedelta只支持 days、seconds 和 microseconds不支持 months 和 years——因为月份和年份的长度不是固定的28-31天365/366天。如果需要按月或按年进行计算推荐使用第三方库dateutil的relativedelta。fromdatetimeimportdatetime,timedelta nowdatetime.now()# 日期加减tomorrownowtimedelta(days1)yesterdaynow-timedelta(days1)next_weeknowtimedelta(weeks1)three_hours_laternowtimedelta(hours3)half_hour_agonow-timedelta(minutes30)print(f明天:{tomorrow.strftime(%Y-%m-%d)})print(f昨天:{yesterday.strftime(%Y-%m-%d)})print(f下周:{next_week.strftime(%Y-%m-%d)})print(f3小时后:{three_hours_later.strftime(%H:%M)})print(f半小时前:{half_hour_ago.strftime(%H:%M)})# 计算两个日期的差值birthdaydatetime(1995,8,22)age_deltanow-birthdayprint(f自出生已过:{age_delta.days}天)print(f约{age_delta.days//365}年)# 计算项目截止时间deadlinedatetime(2024,12,31,23,59,59)remainingdeadline-nowprint(f距离截止还有:{remaining.days}天{remaining.seconds//3600}小时)六、time模块补充time模块提供更底层的操作主要处理时间戳和程序休眠。time和datetime的分工是time模块处理底层的时间戳和系统时钟操作datetime模块提供高级的面向对象的日期时间接口。在实际开发中你可以根据需求灵活选择需要处理人类可读的日期和时间时用datetime需要操作时间戳或高精度计时时用time。importtime# 当前时间戳自1970-01-01以来的秒数timestamptime.time()print(f当前时间戳:{timestamp})# 休眠print(等待3秒...)time.sleep(3)print(继续执行)# 时间戳 ↔ 结构化时间local_timetime.localtime(timestamp)print(f本地时间:{time.strftime(%Y-%m-%d %H:%M:%S,local_time)})# UTC结构化时间utc_timetime.gmtime(timestamp)print(fUTC时间:{time.strftime(%Y-%m-%d %H:%M:%S,utc_time)})# 结构化时间 → 时间戳new_timestamptime.mktime(local_time)print(f转回时间戳:{new_timestamp})# 性能计时高精度starttime.perf_counter()resultsum(range(1000000))endtime.perf_counter()print(f计算耗时:{end-start:.6f}秒)七、实战案例理论知识最终要落地到实际场景。以下四个案例覆盖了时间日期处理最常见的工作场景——日期范围生成、日志时间戳解析、倒计时器和工作日计算。每个案例都可以作为模板代码直接使用。7.1 日期范围生成器fromdatetimeimportdatetime,timedeltadefdate_range(start_date,end_date):生成两个日期之间的所有日期currentstart_datewhilecurrentend_date:yieldcurrent currenttimedelta(days1)# 生成某月所有日期startdatetime(2024,1,1)enddatetime(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:matchre.search(pattern,line)ifmatch:ts_strmatch.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:tsparse_log_timestamp(line)ifts:print(f{ts}-{line})7.3 简易倒计时器fromdatetimeimportdatetime,timedeltaimporttimedefcountdown(target_desc,target_datetime):显示活动倒计时whileTrue:nowdatetime.now()remainingtarget_datetime-nowifremaining.total_seconds()0:print(f\r{target_desc}已到来 *20)breakdaysremaining.days hours,remainderdivmod(remaining.seconds,3600)minutes,secondsdivmod(remainder,60)displayf\r距离{target_desc}还有:{days}天{hours:02d}时{minutes:02d}分{seconds:02d}秒print(display,end,flushTrue)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个工作日currentstart_date remainingdayswhileremaining0:currenttimedelta(days1)# weekday(): 0周一, 6周日ifcurrent.weekday()5:# 周一至周五remaining-1returncurrentdefbusiness_days_between(start,end):计算两个日期之间的工作日天数currentstart count0whilecurrentend:ifcurrent.weekday()5:count1currenttimedelta(days1)returncount# 使用示例todaydatetime.now().replace(hour0,minute0,second0,microsecond0)deadlineadd_business_days(today,10)print(f今天:{today.strftime(%Y-%m-%d)})print(f10个工作日后:{deadline.strftime(%Y-%m-%d)})startdatetime(2024,1,1)enddatetime(2024,1,31)working_daysbusiness_days_between(start,end)print(f2024年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 体验