深入浅出 Python datetime:date、time 与 timedelta 完全指南
·
一、date —— 处理日期(年-月-日)
date 对象用于表示一个纯粹的日期,不包含时间部分。
1. 创建 date 对象
from datetime import date
# 方式1:直接传入年、月、日
d1 = date(2026, 7, 16)
print(d1) # 2026-07-16
# 方式2:获取当前日期
d2 = date.today()
print(d2) # 2026-07-16(举例)
2. 常用属性和方法
d = date(2026, 7, 16)
# 获取年/月/日
print(d.year) # 2026
print(d.month) # 7
print(d.day) # 16
# 获取星期几(周一=0,周日=6)
print(d.weekday()) # 3(周四)
# 获取星期几(周一=1,周日=7)
print(d.isoweekday()) # 4
# 转为 ISO 格式字符串
print(d.isoformat()) # 2026-07-16
# 自定义格式化
print(d.strftime("%Y年%m月%d日")) # 2026年07月16日
# 解析字符串为 date 对象
d_from_str = date.fromisoformat("2026-07-16")
print(d_from_str) # 2026-07-16
3. 常用场景
-
记录用户注册日期
-
生成每日报表的文件名
-
判断某个日期是周几
二、time —— 处理时间(时:分:秒.微秒)
time 对象用于表示一天中的某个时间点,不包含日期。
1. 创建 time 对象
from datetime import time
# 时、分、秒、微秒(微秒可选)
t1 = time(14, 30, 45, 123456)
print(t1) # 14:30:45.123456
# 只传时和分
t2 = time(8, 0)
print(t2) # 08:00:00
2. 常用属性和方法
t = time(14, 30, 45, 123456)
print(t.hour) # 14
print(t.minute) # 30
print(t.second) # 45
print(t.microsecond) # 123456
# 格式化输出
print(t.strftime("%H:%M:%S")) # 14:30:45
print(t.strftime("%I:%M %p")) # 02:30 PM(12小时制)
# 解析字符串
t_from_str = time.fromisoformat("14:30:45.123456")
print(t_from_str)
3. 常用场景
-
设置每日定时任务的时间点
-
记录操作发生的具体时刻
-
比较两个时间点的先后
三、timedelta —— 时间差/时间间隔
timedelta 是三个中最特别的,它不表示一个具体时刻,而是表示时间的长度,比如“3天”、“5小时”、“2.5秒”。
1. 创建 timedelta 对象
from datetime import timedelta
# 可以组合使用各种参数
td1 = timedelta(days=3, hours=5, minutes=30)
print(td1) # 3 days, 5:30:00
# 常用参数:days, seconds, microseconds, milliseconds, minutes, hours, weeks
td2 = timedelta(weeks=1) # 7天
print(td2) # 7 days, 0:00:00
2. 常用操作
(1) 日期/时间的加减
from datetime import date, datetime
today = date(2026, 7, 16)
delta = timedelta(days=10)
future = today + delta
past = today - delta
print(future) # 2026-07-26
print(past) # 2026-07-06
(2) 两个日期/时间相减得到 timedelta
d1 = date(2026, 7, 16)
d2 = date(2026, 7, 1)
diff = d1 - d2
print(diff) # 15 days, 0:00:00
print(diff.days) # 15
print(diff.total_seconds()) # 1296000.0
(3) 常用属性和方法
td = timedelta(days=5, hours=3, minutes=20)
print(td.days) # 5
print(td.seconds) # 12000(3小时20分钟换算成秒)
print(td.total_seconds()) # 444000.0(总秒数)
3. 常用场景
-
计算两个日期之间的天数差
-
给当前时间加上/减去若干天/小时
-
设置缓存过期时间
-
计算程序运行耗时
四、三个对象之间的协作关系
| 操作 | 结果类型 | 示例 |
|---|---|---|
date ± timedelta |
date |
today + timedelta(days=1) |
datetime ± timedelta |
datetime |
now + timedelta(hours=2) |
date - date |
timedelta |
d1 - d2 |
datetime - datetime |
timedelta |
dt1 - dt2 |
time 不支持与 timedelta 直接运算(需结合 datetime) |
— | — |
注意:
time对象不能直接和timedelta做加减,需要先组合成datetime。
补充一:datetime 模块核心类综合对比表
建议放在"三个对象的协作关系总览"之后,"综合实战"之前
| 对比维度 | date | time | datetime | timedelta |
|---|---|---|---|---|
| 表示内容 | 日期(年-月-日) | 时间(时:分:秒.微秒) | 日期 + 时间 | 时间差/时间间隔 |
| 核心属性 | year, month, day |
hour, minute, second, microsecond |
year, month, day, hour, minute, second, microsecond |
days, seconds, microseconds |
| 创建方式 | date(2026,7,16)date.today()date.fromisoformat() |
time(14,30,45)time.fromisoformat() |
datetime(2026,7,16,14,30)datetime.now()datetime.fromisoformat() |
timedelta(days=3, hours=5)两个日期相减 |
| 是否可加减 | ✅ 可与 timedelta 运算 |
❌ 不可直接与 timedelta 运算 |
✅ 可与 timedelta 运算 |
✅ 可与数字/另一个 timedelta 运算 |
| 比较操作 | ✅ 支持(==, <, > 等) | ✅ 支持(==, <, > 等) | ✅ 支持(==, <, > 等) | ✅ 支持(==, <, > 等) |
| 格式化输出 | strftime() |
strftime() |
strftime() |
直接 print() 或手动格式化 |
| 字符串解析 | fromisoformat()strptime() |
fromisoformat()strptime() |
fromisoformat()strptime() |
❌ 不直接支持(需手动计算) |
| replace() | ✅ 修改年/月/日 | ✅ 修改时/分/秒/微秒 | ✅ 修改任意字段 | ❌ 无此方法(但可直接构造新对象) |
| 典型场景 | 生日、账单日期、报表日期 | 营业时间、定时任务时刻 | 日志记录、API 时间戳 | 倒计时、缓存过期、耗时统计 |
| 与 timedelta 关系 | date ± td = datedate - date = td |
❌ 不支持 | datetime ± td = datetimedatetime - datetime = td |
td ± td = tdtd * n = td |
快速选择指南
text
你的需求是什么?
│
├── 只需要年月日(不需要时分秒)→ 用 date
│ 例:用户生日、合同生效日期、每日报表
│
├── 只需要时分秒(不需要年月日)→ 用 time
│ 例:商店营业时间、每日提醒时刻
│
├── 同时需要年月日和时分秒 → 用 datetime
│ 例:订单创建时间、日志记录、API 响应时间
│
└── 需要表示时间长度/间隔 → 用 timedelta
例:倒计时、缓存有效期、两个事件间隔
📌 常用组合速查
from datetime import datetime
now = datetime(2026, 7, 16, 14, 30, 45, 123456)
# ===== 日期相关 =====
print(now.strftime("%Y-%m-%d")) # 2026-07-16
print(now.strftime("%Y/%m/%d")) # 2026/07/16
print(now.strftime("%Y年%m月%d日")) # 2026年07月16日
print(now.strftime("%Y-%m-%d (%A)")) # 2026-07-16 (Thursday)
print(now.strftime("%b %d, %Y")) # Jul 16, 2026
print(now.strftime("%B %d, %Y")) # July 16, 2026
print(now.strftime("%a, %b %d")) # Thu, Jul 16
print(now.strftime("%A, %B %d, %Y")) # Thursday, July 16, 2026
print(now.strftime("%m/%d/%Y")) # 07/16/2026
print(now.strftime("%d/%m/%Y")) # 16/07/2026
# ===== 时间相关 =====
print(now.strftime("%H:%M:%S")) # 14:30:45
print(now.strftime("%H:%M")) # 14:30
print(now.strftime("%I:%M %p")) # 02:30 PM
print(now.strftime("%I:%M:%S %p")) # 02:30:45 PM
print(now.strftime("%H:%M:%S.%f")) # 14:30:45.123456
print(now.strftime("%H:%M:%S.%f")[:-3]) # 14:30:45.123(截取毫秒)
# ===== 日期 + 时间 =====
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 2026-07-16 14:30:45
print(now.strftime("%Y-%m-%d %H:%M:%S.%f")) # 2026-07-16 14:30:45.123456
print(now.strftime("%Y-%m-%dT%H:%M:%S")) # 2026-07-16T14:30:45(ISO 风格)
print(now.strftime("%Y-%m-%d %I:%M %p")) # 2026-07-16 02:30 PM
# ===== 文件名/日志安全格式 =====
print(now.strftime("%Y%m%d")) # 20260716
print(now.strftime("%Y%m%d_%H%M%S")) # 20260716_143045
print(now.strftime("%Y-%m-%d_%H-%M-%S")) # 2026-07-16_14-30-45
# ===== 周数相关 =====
print(now.strftime("第%W周")) # 第28周(周一为第一天)
print(now.strftime("第%U周")) # 第28周(周日为第一天)
print(now.strftime("%Y-W%W-%w")) # 2026-W28-4(ISO 周风格)
# ===== 完整的本地格式 =====
print(now.strftime("%c")) # Thu Jul 16 14:30:45 2026
print(now.strftime("%x")) # 07/16/26
print(now.strftime("%X")) # 14:30:45
五、综合实战:一个完整的示例
from datetime import datetime, date, time, timedelta
# 1. 获取当前日期时间
now = datetime.now()
print(f"当前时间: {now}")
# 2. 提取日期和时间
today_date = now.date()
current_time = now.time()
print(f"日期: {today_date}, 时间: {current_time}")
# 3. 计算3天后的日期
after_3_days = today_date + timedelta(days=3)
print(f"3天后: {after_3_days}")
# 4. 计算两个日期差
birthday = date(2026, 10, 1)
days_until_birthday = birthday - today_date
print(f"距离生日还有 {days_until_birthday.days} 天")
# 5. 构造一个特定时间点
appointment = datetime.combine(today_date, time(15, 30))
print(f"预约时间: {appointment}")

六、避坑小贴士
| 问题 | 建议 |
|---|---|
不要混淆 date 和 datetime |
date 只有日期,datetime 包含日期+时间 |
time 不能直接加减 timedelta |
先 combine 成 datetime 再操作 |
| 时区问题 | 上述均为“朴素”时间(无时区),如需时区请用 pytz 或 zoneinfo |
| 格式化字符串记不住 | 常用:%Y-%m-%d %H:%M:%S,查官方文档即可 |
结语
date、time、timedelta 是 Python 时间处理的基石。理解它们的职责边界和协作方式,能让你写出更清晰、更健壮的时间处理代码。
如果你觉得这篇文章有帮助,欢迎点赞、收藏、转发!
更多推荐


所有评论(0)