> 技术文档 > Python 日期时间格式化与解析的瑞士军刀:`strftime()` 与 `strptime()`

Python 日期时间格式化与解析的瑞士军刀:`strftime()` 与 `strptime()`



Python 日期时间格式化与解析的瑞士军刀:strftime()strptime()

在 Python 中处理日期和时间,datetime 模块是我们的核心工具。而在这个模块里,strftime()strptime() 这对互补的方法,则是我们格式化和解析时间字符串的强大助手。它们就像一把瑞士军刀的两面,一面负责把时间对象变成易读的字符串,另一面则负责把字符串变回时间对象,让你能随心所欲地驾驭时间数据的显示与处理。


strftime():将 datetime 对象格式化为字符串

strftime() 方法用于将 datetime 对象(或 datetime 对象)按照你指定的格式格式化成人类可读的字符串。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() 方法需要两个参数:

  1. 要解析的时间字符串
  2. 与时间字符串完全匹配的格式字符串

关键点:提供的格式字符串必须与输入的时间字符串的格式完全一致,包括所有的分隔符、空格、大小写等。

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 模块中的哪些功能呢?