Python 日期时间格式化与解析的瑞士军刀:`strftime()` 与 `strptime()`
Python 日期时间格式化与解析的瑞士军刀:strftime() 与 strptime()
在 Python 中处理日期和时间,datetime 模块是我们的核心工具。而在这个模块里,strftime() 和 strptime() 这对互补的方法,则是我们格式化和解析时间字符串的强大助手。它们就像一把瑞士军刀的两面,一面负责把时间对象变成易读的字符串,另一面则负责把字符串变回时间对象,让你能随心所欲地驾驭时间数据的显示与处理。
strftime():将 datetime 对象格式化为字符串
strftime() 方法用于将 datetime 对象(或 date、time 对象)按照你指定的格式格式化成人类可读的字符串。str 指的是 “string”(字符串),f 指的是 “format”(格式)。
基本用法
通常,我们会先获取一个 datetime 对象,然后调用其 strftime() 方法,并传入一个格式字符串。
from datetime import datetime# 获取当前日期和时间now = datetime.now()print(f\"当前完整的 datetime 对象: {now}\")# 格式化为常见的日期时间字符串formatted_date_time = now.strftime(\"%Y-%m-%d %H:%M:%S\")print(f\"格式化后的日期时间: {formatted_date_time}\")# 示例输出: 格式化后的日期时间: 2025-07-29 19:14:34
解读格式字符串:神奇的百分号 %
strftime() 的强大之处在于它的格式代码。这些代码都以百分号 % 开头,每个都代表了时间或日期的特定部分。掌握这些代码是精通 strftime() 和 strptime() 的关键。
以下是一些最常用和重要的格式代码及其含义:
年份 (Year)
%Y: 四位数的年份(例如:2025)%y: 两位数的年份,不足两位时前面补零(例如:25)
月份 (Month)
%m: 两位数的月份,不足两位时前面补零(01 到 12)(例如:07表示七月)%B: 月份的全称(例如:July或七月,取决于系统区域设置)%b或%h: 月份的缩写(例如:Jul)
日期 (Day)
%d: 两位数的日期,不足两位时前面补零(01 到 31)(例如:29)%j: 一年中的第几天,三位数字,不足三位时前面补零(001 到 366)(例如:210)
星期 (Weekday)
%w: 星期几(数字表示,0 是星期天,6 是星期六)(例如:2表示星期二)%A: 星期几的全称(例如:Tuesday或星期二)%a: 星期几的缩写(例如:Tue)
小时 (Hour)
%H: 24 小时制的小时,两位数,不足两位时前面补零(00 到 23)(例如:19表示下午 7 点)%I: 12 小时制的小时,两位数,不足两位时前面补零(01 到 12)(例如:07表示 7 点)%p: AM 或 PM(例如:PM)
分钟 (Minute)
%M: 两位数的分钟,不足两位时前面补零(00 到 59)(例如:14)
秒 (Second)
%S: 两位数的秒,不足两位时前面补零(00 到 59)(例如:34)%f: 微秒,六位数字(000000 到 999999)(例如:123456)
时间戳与时区 (Timestamp & Timezone)
%z: UTC 偏移量,以+HHMM或-HHMM格式表示。如果时区信息不可用,则为空字符串(例如:+0800表示东八区)%Z: 时区名称。如果时区信息不可用,则为空字符串(例如:CST表示中国标准时间)%U: 一年中的第几周(以星期天作为一周的开始,00 到 53)%W: 一年中的第几周(以星期一作为一周的开始,00 到 53)%c: 本地日期和时间的合适表示(例如:Tue Jul 29 19:14:34 2025)%x: 本地日期的合适表示(例如:07/29/25)%X: 本地时间的合适表示(例如:19:14:34)
特殊字符
%%: 百分号字面量。如果你想在输出中显示一个%符号,就用%%。
综合示例
from datetime import datetimenow = datetime.now()print(f\"当前时间: {now}\")print(\"\\n--- 常见日期时间格式示例 ---\")print(f\"ISO 格式: {now.strftime(\'%Y-%m-%dT%H:%M:%S\')}\")print(f\"中文常用格式: {now.strftime(\'%Y年%m月%d日 %H时%M分%S秒\')}\")print(f\"只显示日期: {now.strftime(\'%Y/%m/%d\')}\")print(f\"只显示时间: {now.strftime(\'%I:%M %p\')}\") # 12小时制带AM/PMprint(\"\\n--- 星期和月份示例 ---\")print(f\"今天是: {now.strftime(\'%A\')}\")print(f\"今天是(缩写): {now.strftime(\'%a\')}\")print(f\"现在是: {now.strftime(\'%B\')}\")print(f\"现在是(缩写): {now.strftime(\'%b\')}\")print(\"\\n--- 其他细节示例 ---\")print(f\"当前是今年第 {now.strftime(\'%j\')} 天\")print(f\"星期几(数字,0是周日): {now.strftime(\'%w\')}\")print(f\"带微秒: {now.strftime(\'%H:%M:%S.%f\')}\")print(f\"显示百分号: {now.strftime(\'完成度:100%%\')}\")
strptime():将时间字符串解析为 datetime 对象
与 strftime() 相反,strptime()(“string parse time” 的缩写)方法用于将时间字符串解析(转换)回 datetime 对象。这在从文件、数据库或用户输入中读取时间数据时非常有用。
strptime() 方法需要两个参数:
- 要解析的时间字符串。
- 与时间字符串完全匹配的格式字符串。
关键点:提供的格式字符串必须与输入的时间字符串的格式完全一致,包括所有的分隔符、空格、大小写等。
strptime() 基本用法
from datetime import datetime# 一个时间字符串time_string_1 = \"2023-10-26 14:30:00\"# 对应的格式字符串,必须严格匹配format_string_1 = \"%Y-%m-%d %H:%M:%S\"# 使用 strptime() 进行解析dt_object_1 = datetime.strptime(time_string_1, format_string_1)print(f\"解析后的 datetime 对象 1: {dt_object_1}\")print(f\"类型: {type(dt_object_1)}\")# 另一个时间字符串,格式不同time_string_2 = \"Oct 26, 2023 02:30 PM\"# 对应的格式字符串,依然要严格匹配format_string_2 = \"%b %d, %Y %I:%M %p\"dt_object_2 = datetime.strptime(time_string_2, format_string_2)print(f\"解析后的 datetime 对象 2: {dt_object_2}\")
常见错误:格式字符串不匹配
如果格式字符串与实际的时间字符串不匹配,strptime() 会抛出 ValueError 异常。这是最常见的错误。
from datetime import datetime# 错误的格式字符串示例time_string_error = \"2023/10/26\"format_string_error = \"%Y-%m-%d\" # 期望的是 \'-\',但实际是 \'/\'try: datetime.strptime(time_string_error, format_string_error)except ValueError as e: print(f\"\\n解析错误: {e}\") print(\"错误提示:格式字符串与时间字符串不匹配!\")# 正确的格式字符串correct_format_string = \"%Y/%m/%d\"dt_object_correct = datetime.strptime(time_string_error, correct_format_string)print(f\"正确解析: {dt_object_correct}\")
注意事项与常见问题
1. 本地化 (Locale-dependent)
%A, %a, %B, %b, %c, %x, %X 等格式代码的输出或解析会受到你系统区域设置 (locale) 的影响。例如,在中文区域设置下,%A 可能输出“星期二”,而在英文区域设置下则输出“Tuesday”。如果你需要跨平台一致的输出或解析,最好避免使用这些依赖区域设置的代码,或者在代码中显式设置区域设置(例如 locale.setlocale(locale.LC_TIME, \'en_US.UTF-8\'))。
2. 时区信息 (Timezone Information)
默认情况下,datetime 对象是天真 (naive) 的,不包含时区信息。
strftime()只能在datetime对象包含时区信息时(即它是感知 (aware) 的)才能正确使用%z和%Z。strptime()解析出的datetime对象通常也是天真的。如果你的时间字符串包含时区信息(如+0800),你需要确保格式字符串中包含%z或%Z。但即使解析出来了,这个datetime对象依然是天真的,若要进行正确的时区转换或比较,你通常需要结合pytz或 Python 3.9+ 的zoneinfo模块来创建感知datetime对象。
3. 严格匹配
strptime() 对格式字符串的匹配是非常严格的。任何不匹配的字符(包括空格、标点符号、大小写)都会导致解析失败并抛出 ValueError。这既是它的优点(精确),也是缺点(不够容错)。
4. 性能考量
对于非常大规模的时间字符串格式化或解析,虽然 strftime() 和 strptime() 的性能通常不是瓶颈,但如果真的遇到性能问题,可以考虑针对特定场景进行优化,例如:
- 如果格式固定,可以尝试预编译格式字符串。
- 对于复杂的、不规则的时间字符串解析,可以考虑使用第三方库如
dateutil,它提供了更强大的模糊解析能力,但通常解析速度会慢一些。
总结
strftime() 和 strptime() 是 Python datetime 模块中一对互补且不可或缺的方法。
strftime()负责将datetime对象格式化为人类可读的字符串,让你能够自由定制时间的显示方式。strptime()负责将时间字符串解析回datetime对象,是处理外部时间数据的基础。
掌握这两个方法以及它们所使用的格式代码,你就能在 Python 中自如地进行日期和时间的格式化与解析,让你的应用程序在处理时间数据时更加强大和灵活。你还想了解 datetime 模块中的哪些功能呢?


