Python中datetime模块详细教程


🕓 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 必须是两位(0112),不能是 112。

六、时间计算(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))

⚠️ 雷点:

  • timedelta 的参数是关键字参数:days=, hours=, minutes=,不要直接传位置参数。
  • 微秒(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)

⚠️ 雷点:

  • timestamp() 默认基于本地时区;
  • 若需要 UTC 时间,请使用 datetime.utcnow().astimezone()

九、时区处理(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())

十二、常见雷区总结 ⚡

雷区 错误写法 正确写法
模块与类混用 datetime.now() datetime.datetime.now()from datetime import datetime
构造时间对象 datetime.datetime.time(6, 0) time(6, 0)
strftime 格式错误 %y-%m-%d (小写 y) %Y-%m-%d (大写 Y)
时区比较 直接比较 naive 与 aware 先用 .astimezone() 统一
字符串解析 格式不匹配时报错 用正确的 %Y-%m-%d %H:%M:%S
时间计算 datetime + 3 datetime + timedelta(days=3)

十三、总结:使用建议 🧭

推荐导入方式:

from datetime import datetime, date, time, timedelta, timezone

推荐实践顺序:

  1. 使用 datetime.now() 获取当前时间;
  2. 使用 strftime() 格式化输出;
  3. 使用 strptime() 从字符串解析;
  4. 使用 timedelta 做加减;
  5. 使用 timezone 管理时区;
  6. 避免直接混用模块名 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.utcnow()
""")

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 模块演示完毕

文章作者: 0xdadream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0xdadream !
评论
  目录