【Python-Day 26】解锁时间魔法:深入解析 time 与 datetime 模块
Langchain系列文章目录
01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南
04-玩转 LangChain:从文档加载到高效问答系统构建的全程实战
05-玩转 LangChain:深度评估问答系统的三种高效方法(示例生成、手动评估与LLM辅助评估)
06-从 0 到 1 掌握 LangChain Agents:自定义工具 + LLM 打造智能工作流!
07-【深度解析】从GPT-1到GPT-4:ChatGPT背后的核心原理全揭秘
08-【万字长文】MCP深度解析:打通AI与世界的“USB-C”,模型上下文协议原理、实践与未来
Python系列文章目录
PyTorch系列文章目录
机器学习系列文章目录
深度学习系列文章目录
Java系列文章目录
JavaScript系列文章目录
Python系列文章目录
01-【Python-Day 1】告别编程恐惧:轻松掌握 Python 安装与第一个程序的 6 个步骤
02-【Python-Day 2】掌握Python基石:变量、内存、标识符及int/float/bool数据类型
03-【Python-Day 3】玩转文本:字符串(String)基础操作详解 (上)
04-【Python-Day 4】玩转文本:Python 字符串常用方法深度解析 (下篇)
05-【Python-Day 5】Python 格式化输出实战:%、format()、f-string 对比与最佳实践
06- 【Python-Day 6】从零精通 Python 运算符(上):算术、赋值与比较运算全解析
07-【Python-Day 7】从零精通 Python 运算符(下):逻辑、成员、身份运算与优先级规则全解析
08-【Python-Day 8】从入门到精通:Python 条件判断 if-elif-else 语句全解析
09-【Python-Day 9】掌握循环利器:for 循环遍历序列与可迭代对象详解
10-【Python-Day 10】Python 循环控制流:while 循环详解与 for 循环对比
11-【Python-Day 11】列表入门:Python 中最灵活的数据容器 (创建、索引、切片)
12-【Python-Day 12】Python列表进阶:玩转添加、删除、排序与列表推导式
13-【Python-Day 13】Python 元组 (Tuple) 详解:从创建、操作到高级应用场景一网打尽
14-【Python-Day 14】玩转Python字典(上篇):从零开始学习创建、访问与操作
15-【Python-Day 15】深入探索 Python 字典 (下):常用方法、遍历、推导式与嵌套实战
16-【Python-Day 16】代码复用基石:详解 Python 函数的定义与调用
17-【Python-Day 17】玩转函数参数(上):轻松掌握位置、关键字和默认值
18-【Python-Day 18】玩转函数参数(下):*args 与 **kwargs 终极指南
19-【Python-Day 19】函数的回响:深入理解 return
语句与返回值
20-【Python-Day 20】揭秘Python变量作用域:LEGB规则与global/nonlocal关键字详解
21-【Python-Day 21】一行搞定!Python lambda 匿名函数的妙用与实战
22-【Python-Day 22】代码的基石:模块(Module)的导入与使用详解
23-【Python-Day 23】Python 模块化编程实战:创建、导入及 sys.path 深度解析
24-【Python-Day 24】告别杂乱代码!一文掌握 Python 包(Package)的创建与使用
25-【Python-Day 25】玩转数字:精通 math 与 random 模块,从数学运算到随机抽样
26-【Python-Day 26】解锁时间魔法:深入解析 time 与 datetime 模块
文章目录
- Langchain系列文章目录
- Python系列文章目录
- PyTorch系列文章目录
- 机器学习系列文章目录
- 深度学习系列文章目录
- Java系列文章目录
- JavaScript系列文章目录
- Python系列文章目录
- 前言
- 一、time 模块:时间的使者
- 1.1 时间戳 (Timestamp)
- (1) 什么是时间戳?
- (2) 获取当前时间戳
- 1.2 时间元组 (struct_time)
- (1) 获取本地时间元组
- (2) 获取 UTC 时间元组
- 1.3 时间格式化与解析
- (1) 格式化:从 `struct_time` 到字符串
- (2) 解析:从字符串到 `struct_time`
- 1.4 实用函数 `time.sleep()`
- 二、datetime 模块:时间的高级管家
- 2.1 `datetime` 模块的核心对象
- 2.1.1 `date` 对象:专注日期
- 2.1.2 `time` 对象:专注时间
- 2.1.3 `datetime` 对象:日期与时间的结合体
- (1) 创建 `datetime` 对象
- (2) `datetime` 对象与时间戳的转换
- 2.2 时间的“加减法”:`timedelta` 对象
- 2.3 `datetime` 的格式化与解析
- 三、time 与 datetime 的抉择
- 四、实战演练:一个简单的倒计时程序
- 五、总结
前言
在编程世界里,时间不仅仅是墙上的时钟,它更是日志记录、数据分析、任务调度等无数应用场景的核心。无论是计算一个操作耗时多久,还是处理用户的生日信息,亦或是安排一个定时任务,我们都离不开对日期和时间的精准操控。Python 提供了功能强大的内建模块来处理这些需求,其中最核心的两个就是 time
和 datetime
。本文将带你系统地学习这两个模块,从基础概念到高级应用,让你彻底掌握在 Python 中驾驭时间的魔法。
一、time 模块:时间的使者
time
模块提供了主要与 UNIX 时间戳(Unix Timestamp)交互的底层函数。它更接近操作系统层面,适合用于获取时间戳、程序计时等场景。
1.1 时间戳 (Timestamp)
(1) 什么是时间戳?
时间戳是一种表示时间的方式,它指的是从一个固定的“纪元”(Epoch)开始,到当前时刻所经过的秒数。在大多数系统中,这个纪元被定义为 1970年1月1日00:00:00 (UTC)。时间戳是一个浮点数,可以精确到微秒。它不关心时区,是一种绝对的时间表示。
(2) 获取当前时间戳
使用 time.time()
函数可以轻松获取当前的 Unix 时间戳。
import time# 获取当前时间戳
current_timestamp = time.time()
print(f"当前的时间戳是: {current_timestamp}")
# 输出: 当前的时间戳是: 1718270425.123456 (这个值会随时间变化)
应用场景:非常适合用来计算代码执行耗时。
start_time = time.time()# 模拟一个耗时操作
sum = 0
for i in range(1000000):sum += iend_time = time.time()print(f"代码块执行耗时: {end_time - start_time} 秒")
1.2 时间元组 (struct_time)
时间戳虽然精确,但对人类来说可读性很差。time
模块使用一个名为 time.struct_time
的元组对象来更结构化地表示时间。它包含9个元素:
索引 | 属性名 | 值范围 |
---|---|---|
0 | tm_year | (例如, 2025) |
1 | tm_mon | 1 到 12 |
2 | tm_mday | 1 到 31 |
3 | tm_hour | 0 到 23 |
4 | tm_min | 0 到 59 |
5 | tm_sec | 0 到 61 (考虑闰秒) |
6 | tm_wday | 0 到 6 (周一为0) |
7 | tm_yday | 1 到 366 (一年中的第几天) |
8 | tm_isdst | 0, 1, -1 (是否夏令时) |
(1) 获取本地时间元组
time.localtime()
函数可以将一个时间戳转换成本地时区的 struct_time
。如果不提供参数,则默认使用当前时间戳。
# 获取本地时间的 struct_time
local_time_struct = time.localtime()
print(f"本地时间元组: {local_time_struct}")
print(f"今年是: {local_time_struct.tm_year} 年")
print(f"今天是本周的第 {local_time_struct.tm_wday + 1} 天")
(2) 获取 UTC 时间元组
time.gmtime()
功能类似,但它返回的是 UTC (协调世界时,也称格林威治标准时间) 的 struct_time
。
# 获取 UTC 时间的 struct_time
utc_time_struct = time.gmtime()
print(f"UTC 时间元组: {utc_time_struct}")
1.3 时间格式化与解析
time
模块中最实用的功能之一就是将时间在“结构化对象”和“字符串”之间来回转换。
(1) 格式化:从 struct_time
到字符串
time.strftime(format, t)
函数可以将一个 struct_time
对象(参数 t
)按照指定的格式(参数 format
)转换成一个字符串。
local_time_struct = time.localtime()# 格式化成 "年-月-日 时:分:秒"
formatted_time = time.strftime("%Y-%m-%d %H:%M:%S", local_time_struct)
print(f"格式化后的本地时间: {formatted_time}")
# 输出: 格式化后的本地时间: 2025-06-13 05:00:25 (示例)
(2) 解析:从字符串到 struct_time
time.strptime(string, format)
函数是 strftime
的逆操作,它可以将一个字符串(参数 string
)按照指定的格式(参数 format
)解析成一个 struct_time
对象。
time_string = "2025-10-01 08:30:00"
format_pattern = "%Y-%m-%d %H:%M:%S"# 将字符串解析为 struct_time
parsed_time_struct = time.strptime(time_string, format_pattern)
print(f"解析后的时间元组: {parsed_time_struct}")
print(f"解析出的年份是: {parsed_time_struct.tm_year}")
注意:解析时,字符串的格式必须与 format
参数严格匹配,否则会抛出 ValueError
异常。
1.4 实用函数 time.sleep()
time.sleep(secs)
函数可以让当前程序的执行暂停指定的秒数(secs
可以是浮点数,以实现毫秒级的暂停)。
print("程序开始...")
time.sleep(2.5) # 暂停 2.5 秒
print("2.5 秒后,程序继续执行!")
二、datetime 模块:时间的高级管家
如果说 time
模块是处理时间的基础工具,那么 datetime
模块就是功能更强大、设计更现代的“时间瑞士军刀”。它以面向对象的方式封装了日期和时间的处理,使用起来更直观、更方便。
2.1 datetime
模块的核心对象
datetime
模块主要包含以下几个核心类:
date
:表示日期(年、月、日)。time
:表示时间(时、分、秒、微秒)。datetime
:表示日期和时间(年、月、日、时、分、秒、微秒)。timedelta
:表示两个date
、time
或datetime
对象之间的时间差。
2.1.1 date
对象:专注日期
date
对象只关心年、月、日。
from datetime import date# 创建一个 date 对象
d = date(2025, 10, 1)
print(f"日期对象: {d}")
print(f"年份: {d.year}, 月份: {d.month}, 日: {d.day}")# 获取今天的 date 对象
today = date.today()
print(f"今天是: {today}")
2.1.2 time
对象:专注时间
time
对象只关心时、分、秒、微秒,与日期无关。
from datetime import time# 创建一个 time 对象
t = time(14, 30, 55, 123456)
print(f"时间对象: {t}")
print(f"小时: {t.hour}, 分钟: {t.minute}, 秒: {t.second}, 微秒: {t.microsecond}")
2.1.3 datetime
对象:日期与时间的结合体
这是最常用的对象,它包含了 date
和 time
的所有信息。
(1) 创建 datetime
对象
from datetime import datetime# 直接创建
dt = datetime(2025, 10, 1, 10, 30, 0)
print(f"创建的 datetime 对象: {dt}")# 获取当前本地日期和时间
now = datetime.now()
print(f"当前本地时间: {now}")# 获取当前 UTC 日期和时间
utcnow = datetime.utcnow()
print(f"当前 UTC 时间: {utcnow}")
(2) datetime
对象与时间戳的转换
datetime
对象可以轻松地与时间戳进行互换。
from datetime import datetime# 获取当前时间
now = datetime.now()
print(f"当前时间对象: {now}")# datetime 对象 -> 时间戳
timestamp = now.timestamp()
print(f"转换后的时间戳: {timestamp}")# 时间戳 -> datetime 对象
dt_from_ts = datetime.fromtimestamp(timestamp)
print(f"从时间戳恢复的时间对象: {dt_from_ts}")
2.2 时间的“加减法”:timedelta
对象
timedelta
对象是 datetime
模块的一大亮点,它代表一个时间段或持续时间,让日期时间的计算变得异常简单。
from datetime import datetime, timedelta# 获取当前时间
now = datetime.now()
print(f"当前时间: {now}")# 创建一个表示“1天12小时”的时间差
delta = timedelta(days=1, hours=12)# 计算未来时间
future_time = now + delta
print(f"1天12小时后: {future_time}")# 计算过去时间
past_time = now - delta
print(f"1天12小时前: {past_time}")# 计算两个 datetime 对象的时间差
dt1 = datetime(2025, 1, 1)
dt2 = datetime(2025, 1, 31)
diff = dt2 - dt1
print(f"两个日期相差: {diff.days} 天")
2.3 datetime
的格式化与解析
datetime
对象也拥有 strftime
方法用于格式化,同时 datetime
类也提供了 strptime
类方法用于解析,用法与 time
模块中的版本非常相似。
from datetime import datetimenow = datetime.now()# 格式化:datetime 对象 -> 字符串
formatted_dt = now.strftime("%Y/%m/%d %A %I:%M %p")
print(f"格式化后的 datetime: {formatted_dt}")
# 输出示例: 格式化后的 datetime: 2025/06/13 Friday 05:00 AM# 解析:字符串 -> datetime 对象
date_str = "2025-12-25 18:00:00"
dt_obj = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print(f"从字符串解析的 datetime: {dt_obj}")
三、time 与 datetime 的抉择
初学者可能会困惑,何时使用 time
,何时使用 datetime
?下面这张图和表格可以帮助你理清思路。
graph TDA[时间处理需求] --> B{需要进行日期计算或处理具体日期吗?};B -- 是 --> C[使用 `datetime` 模块];B -- 否 --> D{是否主要处理时间戳或程序计时?};D -- 是 --> E[使用 `time` 模块];D -- 否 --> F[重新评估需求, `datetime` 通常更通用];C --> C1[创建 `date`, `time`, `datetime` 对象];C --> C2[使用 `timedelta` 进行加减];C --> C3[使用 `strftime`/`strptime`];E --> E1[获取时间戳 `time.time()`];E --> E2[程序暂停 `time.sleep()`];E --> E3[与 `struct_time` 转换];
特性 | time 模块 | datetime 模块 | 选择建议 |
---|---|---|---|
核心 | 面向过程,函数驱动 | 面向对象,通过 date , time , datetime 对象操作 | 优先选择 datetime ,除非有特定需求。 |
数据模型 | 时间戳 (浮点数) 和 struct_time (元组) | 功能丰富的 date , time , datetime , timedelta 对象 | datetime 的对象模型更直观,易于理解和使用。 |
功能范围 | 基础的时间获取、格式化、转换、程序暂停 | 涵盖 time 的功能,并增加了强大的日期时间算术运算 | 需要日期计算(如加减天数)时,必须使用 datetime 。 |
时区处理 | 时区支持有限,主要依赖本地时区和 UTC | 提供了对时区信息(tzinfo )的更好支持(虽然需要配合第三方库如pytz ) | 对于复杂的时区应用,datetime 是基础。 |
典型场景 | 计算代码执行时间、生成与系统底层兼容的时间戳、sleep | 日志记录、数据分析、Web 应用、任务调度、任何需要处理具体日期和时间的场景 | 日常开发和应用层编程,95% 的情况应使用 datetime 。 |
四、实战演练:一个简单的倒计时程序
让我们用 datetime
和 time
模块的知识来编写一个实用的倒计时程序。
from datetime import datetime
import timedef countdown(target_date_str):"""一个简单的倒计时函数:param target_date_str: 目标日期字符串,格式为 "YYYY-MM-DD HH:MM:SS""""try:# 1. 使用 datetime.strptime 解析目标日期字符串为 datetime 对象target_date = datetime.strptime(target_date_str, "%Y-%m-%d %H:%M:%S")print(f"目标时间: {target_date.strftime('%Y年%m月%d日 %H:%M:%S')}")print("倒计时开始!")# 2. 循环直到当前时间超过目标时间while True:# 获取当前时间now = datetime.now()# 如果当前时间已超过目标,则结束if now >= target_date:print("\n时间到!")break# 3. 使用 timedelta 计算剩余时间remaining = target_date - now# 为了更清晰地显示,我们手动计算天、时、分、秒# remaining.total_seconds() 返回总秒数total_seconds = int(remaining.total_seconds())days, rem_seconds = divmod(total_seconds, 86400) # 86400 = 24 * 60 * 60hours, rem_seconds = divmod(rem_seconds, 3600) # 3600 = 60 * 60minutes, seconds = divmod(rem_seconds, 60)# 4. 使用 \r 实现单行刷新,\r 表示回车,将光标移到行首print(f"\r剩余时间: {days} 天 {hours:02d} 时 {minutes:02d} 分 {seconds:02d} 秒", end="")# 5. 使用 time.sleep(1) 每秒刷新一次time.sleep(1)except ValueError:print("错误:日期格式不正确!请输入 'YYYY-MM-DD HH:MM:SS' 格式。")# --- 程序入口 ---
if __name__ == "__main__":# 设置一个未来的时间点作为倒计时目标target = "2026-01-01 00:00:00"countdown(target)
这个例子完美地结合了两个模块的优点:使用 datetime
进行精准的日期解析和时间差计算,使用 time.sleep()
控制程序的执行节奏。
五、总结
恭喜你,完成了对 Python 时间处理核心模块的学习!现在,让我们回顾一下今天的核心知识点:
-
time
模块:是 Python 处理时间的基础模块,更接近底层。它的核心是 Unix 时间戳 (time.time()
) 和 时间元组 (struct_time
)。主要用于获取时间戳、程序计时 (time.sleep()
) 以及基础的格式化 (strftime
) 和解析 (strptime
)。 -
datetime
模块:是更高级、更推荐的面向对象的时间处理模块。它提供了date
,time
,datetime
等直观的对象来表示日期和时间。 -
核心对象:
datetime.datetime
是最常用的对象,它不仅可以表示精确到微秒的日期时间,还能方便地与时间戳进行转换。 -
timedelta
:是datetime
模块的王牌功能,它代表一个时间间隔,使得日期和时间的加减运算变得像整数运算一样简单,是处理日期计算的关键。 -
格式化与解析:
strftime
用于将时间对象转换为人类可读的字符串,而strptime
则反向将字符串解析为时间对象。这是处理时间数据输入输出的必备技能。 -
选择策略:在绝大多数应用开发中,优先使用
datetime
模块。只有在需要进行底层时间戳操作或简单的程序计时时,才考虑使用time
模块。
掌握了 time
和 datetime
,你就拥有了在代码中操控时间流的能力。无论是记录事件发生的瞬间,还是预测未来的某个时刻,你都将游刃有余。继续练习,将这些知识应用到你的项目中去吧!