🕓 Python datetime 模块详细教程(含雷点总结)
一、datetime 模块概述
datetime 是 Python 用于处理日期、时间、时间差、时区等操作的标准库。
主要包含 6 个核心类:
| 类名 | 作用 |
|---|---|
datetime.date |
表示日期(年、月、日) |
datetime.time |
表示时间(时、分、秒、微秒) |
datetime.datetime |
同时表示日期 + 时间 |
datetime.timedelta |
表示时间差 |
datetime.tzinfo |
表示时区信息(基类) |
datetime.timezone |
具体的时区类 |
二、模块导入方式(⚠️第一个雷点)
有两种常见导入方式,推荐第二种:
❌ 错误或容易踩坑写法:
import datetime
now = datetime.now() # ❌ 会报错:module 'datetime' has no attribute 'now'
因为
datetime是模块名,而datetime.now()属于类datetime.datetime。
✅ 正确写法:
from datetime import datetime
now = datetime.now()
或者:
import datetime
now = datetime.datetime.now()
⚠️ 总结:
datetime是模块;datetime.datetime是类;- 所以必须是
datetime.datetime.now()或者直接导入类。
三、获取当前时间与日期
from datetime import datetime, date, time
# 当前日期时间
now = datetime.now()
print(now) # 2025-10-17 11:30:05.234567
# 当前日期
today = date.today()
print(today) # 2025-10-17
# 当前时间
t = datetime.now().time()
print(t) # 11:30:05.234567
四、创建自定义日期时间对象
from datetime import datetime, date, time
# 日期对象
d = date(2025, 10, 17)
print(d.year, d.month, d.day) # 2025 10 17
# 时间对象
t = time(14, 30, 45)
print(t.hour, t.minute, t.second) # 14 30 45
# 日期+时间
dt = datetime(2025, 10, 17, 14, 30, 45)
print(dt) # 2025-10-17 14:30:45
五、日期与字符串互转
✅ 格式化输出(strftime)
from datetime import datetime
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 2025-10-17 11:30:05
print(now.strftime("%A, %B %d, %Y")) # Friday, October 17, 2025
常用格式说明:
| 占位符 | 含义 | 示例 |
|---|---|---|
%Y |
四位年份 | 2025 |
%m |
月(两位) | 10 |
%d |
日(两位) | 17 |
%H |
时(24小时制) | 14 |
%M |
分 | 30 |
%S |
秒 | 45 |
%A |
星期名 | Friday |
✅ 字符串解析为日期对象(strptime)
from datetime import datetime
dt_str = "2025-10-17 11:35:00"
dt = datetime.strptime(dt_str, "%Y-%m-%d %H:%M:%S")
print(dt) # datetime(2025, 10, 17, 11, 35, 0)
⚠️ 雷点:
- 格式必须完全匹配,否则报错
ValueError: time data 'xxx' does not match format。 %m表示月份;strftime()输出两位月份,而strptime()解析时允许省略月份、日期等部分字段的前导零。
六、时间计算(timedelta)
from datetime import datetime, timedelta
now = datetime.now()
# 加减天数
print(now + timedelta(days=1)) # 明天
print(now - timedelta(days=7)) # 一周前
# 加减小时/分钟
print(now + timedelta(hours=2))
print(now - timedelta(minutes=30))
⚠️ 雷点:
- 推荐用
days=、hours=、minutes=等关键字避免混淆。timedelta也接受位置参数,其顺序为 days、seconds、microseconds、milliseconds、minutes、hours、weeks。 - 微秒(
microseconds)容易被忽略,调试日志时可用strftime("%f")查看。
七、比较时间
from datetime import datetime
t1 = datetime(2025, 10, 17, 10, 0)
t2 = datetime(2025, 10, 17, 12, 0)
print(t1 < t2) # True
print(t2 - t1) # 2:00:00
八、获取时间戳(Unix 时间)
from datetime import datetime
now = datetime.now()
timestamp = now.timestamp()
print(timestamp) # 例如 1760643050.123456
# 时间戳 → datetime
dt = datetime.fromtimestamp(timestamp)
print(dt)
⚠️ 雷点:
- Unix 时间戳表示同一绝对时刻,不存在“北京时间戳”和“UTC 时间戳”两套数值;时区影响的是日期时间对象如何解释和显示。
- 无时区的
datetime调用timestamp()时被当作本地时间;带时区的对象按自身时区转换。 - 获取 UTC 时间应使用
datetime.now(timezone.utc),还原 UTC 日期时间用datetime.fromtimestamp(timestamp, timezone.utc)。datetime.utcnow()返回无时区对象,直接对它调用timestamp()可能产生本地时区偏差。
from datetime import datetime, timezone
utc_now = datetime.now(timezone.utc)
timestamp = utc_now.timestamp()
restored = datetime.fromtimestamp(timestamp, timezone.utc)
assert restored == utc_now
九、时区处理(timezone)
from datetime import datetime, timezone, timedelta
# 设置东八区(中国标准时间)
tz = timezone(timedelta(hours=8))
# 当前UTC时间
utc_now = datetime.now(timezone.utc)
print(utc_now)
# 转为北京时间
bj_time = utc_now.astimezone(tz)
print(bj_time)
⚠️ 雷点:
datetime.now()默认“无时区(naive datetime)”,不能直接与带时区的时间比较;- 混用会报
TypeError: can't compare offset-naive and offset-aware datetimes。
十、提取时间部分属性
from datetime import datetime
now = datetime.now()
print(now.year, now.month, now.day)
print(now.hour, now.minute, now.second)
print(now.weekday()) # 星期几(0=周一)
十一、实战案例:判断当前时间阶段
from datetime import datetime, time
def get_time_period():
now = datetime.now().time()
MORNING_START = time(6, 0)
NOON_START = time(13, 30)
EVENING_START = time(20, 30)
NIGHT_END = time(3, 30)
if now >= EVENING_START or now <= NIGHT_END:
return "晚上"
elif MORNING_START <= now < NOON_START:
return "早上"
elif NOON_START <= now < EVENING_START:
return "中午"
else:
return "凌晨"
print(get_time_period())
十二、常见雷区总结 ⚡
| 雷区 | 错误写法 | 正确写法 |
|---|---|---|
| 模块与类混用 | import datetime 后调用 datetime.now() |
模块方式用 datetime.datetime.now();直接导入类后用 datetime.now() |
| 构造时间对象 | datetime.datetime.time(6, 0) |
time(6, 0) |
| 年份位数 | %y 只输出两位年份 |
需要四位年份时使用 %Y;两种格式本身都合法 |
| 时区排序/相减 | 直接混用 naive 与 aware | 先确认无时区值的来源时区,再显式构造带时区对象并转换 |
| 字符串解析 | 格式不匹配时报错 | 用正确的 %Y-%m-%d %H:%M:%S |
| 时间计算 | datetime + 3 |
datetime + timedelta(days=3) |
十三、总结:使用建议 🧭
✅ 推荐导入方式:
from datetime import datetime, date, time, timedelta, timezone
✅ 推荐实践顺序:
- 使用
datetime.now()获取当前时间; - 使用
strftime()格式化输出; - 使用
strptime()从字符串解析; - 使用
timedelta做加减; - 使用
timezone管理时区; - 避免直接混用模块名
datetime和类名datetime。
下面是一份 完整可执行的 Python 脚本,展示了 datetime 模块的全部常用功能、典型实战用法以及常见雷点说明。
你可以直接保存为:
📄 datetime_demo.py
然后在任何 Python 环境中运行(包括 Anaconda、VSCode、PyCharm、命令行等)。
# ==========================================
# datetime 模块完整示例脚本
# 功能: 演示 datetime 的全部主要用法 + 雷点说明
# ==========================================
from datetime import datetime, date, time, timedelta, timezone
print("=" * 80)
print("1️⃣ 获取当前时间、日期、时间戳")
print("=" * 80)
now = datetime.now() # 当前时间(本地)
print("当前时间:", now)
print("当前日期:", date.today())
print("当前时间部分:", now.time())
print("当前时间戳(秒):", now.timestamp())
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("2️⃣ 创建自定义日期与时间对象")
print("=" * 80)
d = date(2025, 10, 17)
t = time(14, 30, 45)
dt = datetime(2025, 10, 17, 14, 30, 45)
print("日期对象:", d)
print("时间对象:", t)
print("完整日期时间对象:", dt)
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("3️⃣ 日期 ↔ 字符串互转 (strftime / strptime)")
print("=" * 80)
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print("格式化输出:", formatted)
parsed = datetime.strptime("2025-10-17 14:35:00", "%Y-%m-%d %H:%M:%S")
print("字符串解析为 datetime 对象:", parsed)
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("4️⃣ 时间加减与时间差 (timedelta)")
print("=" * 80)
tomorrow = now + timedelta(days=1)
last_week = now - timedelta(days=7)
after_3_hours = now + timedelta(hours=3)
before_15_min = now - timedelta(minutes=15)
print("明天:", tomorrow)
print("一周前:", last_week)
print("三小时后:", after_3_hours)
print("十五分钟前:", before_15_min)
delta = tomorrow - now
print("时间差:", delta)
print("相差天数:", delta.days)
print("相差秒数:", delta.seconds)
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("5️⃣ 比较时间对象")
print("=" * 80)
t1 = datetime(2025, 10, 17, 10, 0)
t2 = datetime(2025, 10, 17, 12, 0)
print("t1 < t2 ?", t1 < t2)
print("t2 - t1 =", t2 - t1)
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("6️⃣ 时区转换(UTC ↔ 本地)")
print("=" * 80)
utc_now = datetime.now(timezone.utc)
print("UTC 当前时间:", utc_now)
# 北京时间 = UTC+8
tz_bj = timezone(timedelta(hours=8))
bj_time = utc_now.astimezone(tz_bj)
print("北京时间:", bj_time)
# 再转回 UTC
utc_time_back = bj_time.astimezone(timezone.utc)
print("再转回 UTC:", utc_time_back)
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("7️⃣ 提取时间属性")
print("=" * 80)
print(f"年份: {now.year}, 月份: {now.month}, 日期: {now.day}")
print(f"小时: {now.hour}, 分钟: {now.minute}, 秒: {now.second}")
print(f"星期几 (0=周一): {now.weekday()}")
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("8️⃣ 实战案例:根据当前时间判断时段")
print("=" * 80)
def get_time_period():
"""根据时间返回当前时间段"""
now_time = datetime.now().time()
MORNING_START = time(6, 0)
NOON_START = time(13, 30)
EVENING_START = time(20, 30)
NIGHT_END = time(3, 30)
if now_time >= EVENING_START or now_time <= NIGHT_END:
return "晚上 🌙"
elif MORNING_START <= now_time < NOON_START:
return "早上 🌅"
elif NOON_START <= now_time < EVENING_START:
return "中午 ☀️"
else:
return "凌晨 🌃"
print(f"当前时段:{get_time_period()}")
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("9️⃣ 常见雷点总结 ⚠️")
print("=" * 80)
print("""
⚠️ 雷点 1:datetime 模块与类名同名
❌ datetime.now()
✅ datetime.datetime.now() 或 from datetime import datetime
⚠️ 雷点 2:不能用 datetime.datetime.time(6,0)
✅ 用 time(6,0)
⚠️ 雷点 3:strftime / strptime 格式要完全匹配,否则报 ValueError
⚠️ 雷点 4:混用带时区(aware)与不带时区(naive)datetime 会 TypeError
⚠️ 雷点 5:无时区对象调用 timestamp() 会按本地时间解释
✅ UTC 时间使用 datetime.now(timezone.utc),避免 utcnow().timestamp()
""")
print("\n")
# --------------------------------------------------------------------------------
print("=" * 80)
print("✅ 结束:datetime 模块演示完毕")
print("=" * 80)
💡运行后效果(部分输出示例):
1️⃣ 获取当前时间、日期、时间戳
当前时间: 2025-10-17 11:42:10.232432
当前日期: 2025-10-17
当前时间部分: 11:42:10.232432
当前时间戳(秒): 1760643730.232432
2️⃣ 创建自定义日期与时间对象
日期对象: 2025-10-17
时间对象: 14:30:45
完整日期时间对象: 2025-10-17 14:30:45
...
当前时段: 早上 🌅
...
✅ 结束:datetime 模块演示完毕
评论将在接近此处时加载,也可点击立即加载。