16·模块四:模块与包进阶

标准库之 datetime 与 time 模块

standard-librarydatetimetime

第 16 课 - 标准库之 datetime 与 time 模块

学习目标

完成本课学习后,你将能够:

  1. 理解 datetimetime 两个模块在 Python 时间处理中的定位与区别。
  2. 使用 datetime 模块中的 datetimedatetime 类来创建、操作和格式化日期与时间。
  3. 掌握时间间隔的计算、日期的加减操作。
  4. 了解 time 模块的基本用法,包括获取时间戳和进行程序计时。

核心概念

处理日期和时间是编程中的常见需求,比如记录日志、计算用户年龄、设置定时任务等。Python 提供了强大的标准库来应对这些挑战,其中最主要的就是 datetimetime 模块。

1. datetime 模块:你的日历和时钟 这个模块就像一本实体日历和一个精确的时钟。它提供了面向对象的类,分别表示日期时间日期时间的组合。你可以用它来直观地表示"2023年10月27日下午2点30分",进行"3天后是星期几"的计算,或者把时间格式化成"10/27/2023 14:30"的字符串。它的核心类包括:

  • datetime.date: 只包含日期信息(年、月、日)。
  • datetime.time: 只包含时间信息(时、分、秒、微秒)。
  • datetime.datetime: 包含日期和时间信息,是最常用的类。
  • datetime.timedelta: 表示一个时间间隔(如"3天5小时"),用于日期时间的计算。

2. time 模块:系统时钟的脉搏 这个模块更接近操作系统层面,与底层C语言库交互。它常用的功能是获取时间戳(一个浮点数,表示从1970年1月1日00:00:00 UTC开始经过的秒数),或者让程序暂停执行。它更像是一个系统计时器。

如何选择?

  • 当你需要处理人类可读的日期和时间(比如格式化、解析、做日期加减)时,首选 datetime
  • 当你需要获取时间戳、进行计时(如性能测试)或让程序休眠时,使用 time

代码示例

1. 使用 datetime 模块

import datetime

# 1. 获取当前日期和时间
now = datetime.datetime.now()
print(f"当前完整时间: {now}")  # 输出例如: 2023-10-27 14:30:15.123456

# 2. 创建指定的日期和时间对象
today = datetime.date.today() # 只获取今天的日期
print(f"今天的日期: {today}")

# 手动创建
specific_date = datetime.date(2023, 12, 25)
specific_time = datetime.time(15, 45, 0)
specific_datetime = datetime.datetime(2023, 12, 25, 15, 45, 0)

# 3. 格式化时间:strftime (string format time)
# 将时间对象转换为指定格式的字符串
formatted = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"格式化后: {formatted}") # 输出例如: 2023-10-27 14:30:15

common_format = now.strftime("%B %d, %Y %I:%M %p")
print(f"常见格式: {common_format}") # 输出例如: October 27, 2023 02:30 PM

# 4. 解析时间:strptime (string parse time)
# 将字符串按照指定格式解析成 datetime 对象
time_str = "2023/10/27 14:30"
parsed_time = datetime.datetime.strptime(time_str, "%Y/%m/%d %H:%M")
print(f"解析出的对象: {parsed_time}")

# 5. 时间间隔与计算
today = datetime.date.today()
one_day = datetime.timedelta(days=1)
yesterday = today - one_day
tomorrow = today + one_day
print(f"昨天: {yesterday}, 明天: {tomorrow}")

# 计算两个日期间隔
birth_date = datetime.date(1995, 6, 15)
age_delta = today - birth_date
print(f"你已经出生了 {age_delta.days} 天。")

# datetime 对象之间也可以相减,得到 timedelta
time1 = datetime.datetime(2023, 10, 27, 10, 0)
time2 = datetime.datetime(2023, 10, 27, 14, 30)
time_diff = time2 - time1
print(f"时间间隔: {time_diff}") # 输出: 4:30:00

2. 使用 time 模块

import time

# 1. 获取时间戳
timestamp = time.time()  # 当前时间的时间戳
print(f"当前时间戳: {timestamp}") # 输出例如: 1698384615.123456

# 2. 时间戳转成 struct_time(结构化时间,便于阅读)
local_time = time.localtime(timestamp)
print(f"本地结构化时间: {local_time}")
# 输出类似: time.struct_time(tm_year=2023, tm_mon=10, tm_mday=27, ...)

# 3. 程序计时
start_time = time.time()
# 模拟一个耗时操作
total = 0
for i in range(1000000):
    total += i
end_time = time.time()
elapsed_time = end_time - start_time
print(f"计算循环耗时: {elapsed_time:.4f} 秒")

# 4. 程序休眠
print("开始等待...")
time.sleep(2)  # 程序暂停2秒
print("2秒已过!")

综合示例:游戏技能冷却

import datetime
import time

print(">>> 技能释放!冷却开始。")
skill_cooldown = datetime.timedelta(seconds=5) # 冷却时间5秒
last_used_time = datetime.datetime.now()

# 模拟一段时间的流逝
time.sleep(2)
current_time = datetime.datetime.now()
time_passed = current_time - last_used_time

if time_passed >= skill_cooldown:
    print("冷却完成,可以再次使用!")
else:
    remaining = skill_cooldown - time_passed
    # timedelta对象可以方便地转换为总秒数
    print(f"技能冷却中,还需等待 {remaining.total_seconds():.2f} 秒。")

实践练习

练习1:基础操作

  1. 创建一个 datetime.datetime 对象,表示你的出生日期和时间。
  2. 计算并输出从你出生到现在已经过去了多少天、多少小时(使用 timedelta)。
  3. 将这个出生时间格式化为"YYYY年MM月DD日 HH:MM"的中文字符串。

练习2:时间计算

  1. 获取当前日期。
  2. 计算100天后是哪一天,是星期几。
  3. 计算上个月的同一天是哪一天。

练习3:文件时间戳

  1. 使用 os.path.getctime('你的Python脚本文件名.py') 获取当前脚本文件的创建时间戳(这是一个浮点数)。
  2. 将这个时间戳转换为人类可读的本地时间字符串(格式自定),并打印出来。

常见错误

  1. 混淆 datedatetime 对象date 对象没有 hour, minute 等属性。尝试 datetime.date.today().hour 会报错。需要先确认你需要的是日期还是日期时间。
  2. 时区问题datetime.datetime.now() 返回的是本地时间,而 datetime.datetime.utcnow() 返回的是UTC时间。在不同时区的机器上,now() 的结果会不同,直接比较可能会出错。对于网络应用或跨时区操作,应使用 timezone 信息。
  3. 时间格式字符串错误strftimestrptime 的格式字符串必须严格匹配。例如,格式是 %Y-%m-%d,输入字符串就必须是 2023-10-27,而不是 2023/10/2723-10-27。常见错误是把 %M(分钟)写成 %m(月份)。
  4. 时间戳的误区time.time() 返回的是浮点数,而许多函数(如 time.localtime())需要一个浮点数参数。不要试图将一个 datetime 对象直接传给需要时间戳的函数,应该先用 .timestamp() 方法转换(datetime_obj.timestamp())。
  5. timedelta 与数字的混淆:两个 datetime 对象相减得到的是 timedelta 对象,而不是一个简单的数字。要获取天数,用 .days 属性;获取秒数,用 .seconds 属性或 .total_seconds() 方法。

小结

  • datetime 模块是处理人类可读日期和时间的首选,核心是 datetime.datedatetime.timedatetime.datetimedatetime.timedelta 四个类。
  • time 模块更底层,常用于获取时间戳、让程序休眠和进行简单的计时
  • 格式化使用 strftime()解析使用 strptime(),格式指令(如 %Y, %m, %d)是沟通代码与字符串的桥梁。
  • 日期计算的秘诀是 timedelta。你可以创建一个表示时间间隔的对象,然后与 datedatetime 对象进行加减运算。
  • 始终注意本地时间UTC时间的区别,在需要精确协调的场景下考虑时区信息。

在下一课中,我们将学习如何使用 pip 安装和管理第三方库,这将为你打开 Python 生态系统更广阔的大门。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「第三方库安装与 pip 使用」 以巩固所学知识。