使用 f-string 格式化 Python datetime
最后修改于 2025 年 5 月 11 日
本教程将探讨如何使用 Python 的 f-string 来格式化 datetime 对象,这是一种在 Python 3.6 中引入的简洁易读的方法。f-string 简化了日期和时间格式化,同时提供了优于传统方法的优势。
在许多应用程序中,有效地格式化日期和时间信息至关重要,从在日志和报告中生成人类可读的时间戳,到为 API 和数据库准备日期字符串。Python 内置的 datetime 模块提供了全面的日期和时间操作工具集,包括表示日期、时间以及时间间隔的类。
虽然 strftime() 等旧方法长期以来一直用于 datetime 格式化,但 f-string(格式化字符串字面量)提供了更现代、更直观且通常性能更好的方法来实现相同的结果。f-string 允许通过在字符串前加上 'f' 并将表达式放在大括号 {} 中来将表达式嵌入字符串字面量。当表达式是 datetime 对象时,您可以在冒号后包含格式说明符来控制其字符串表示。这使得代码更清晰,一目了然。
在本教程中,我们将深入探讨使用 f-string 进行 datetime 格式化的各个方面。我们将涵盖常见的格式代码,如何提取和显示 datetime 对象的特定组件(如年、月、日、小时、分钟),以及如何处理更高级的场景,例如特定区域设置的格式化和时区转换。所有示例都利用了 datetime 模块的强大功能和灵活性,并结合了 f-string 的语法糖。
我们将涵盖使用 f-string 的基本 datetime 格式化技术,包括自定义格式、本地化和时区管理。所有示例都使用了 Python 内置的 datetime 模块,该模块提供了处理和操作日期和时间数据的强大工具。
Python 中的 Datetime 格式说明符
Python 的 strftime 和 f-string 格式化提供了一种灵活的方式来表示日期和时间值。格式说明符定义了 datetime 对象如何显示,使得可以轻松地为不同的应用程序、区域设置和可读性偏好调整输出。
下表列出了 Python datetime 模块支持的常见格式说明符
| 说明符 | 描述 | 示例 |
|---|---|---|
| %Y | 带世纪的年份 (0000-9999) | 2025 |
| %y | 不带世纪的年份 (零填充,00-99) | 25 |
| %m | 月份(零填充十进制,01-12) | 02 |
| %B | 完整的月份名称(取决于区域设置) | 二月 |
| %b | 缩写的月份名称(取决于区域设置) | 二月 |
| %d | 月份的日期(零填充,01-31) | 09 |
| %A | 完整的星期名称(取决于区域设置) | 星期一 |
| %a | 缩写的星期名称(取决于区域设置) | 周一 |
| %w | 星期(十进制,0-6,星期日=0) | 1 |
| %u | ISO 8601 星期(1-7,星期一=1) | 2 |
| %H | 小时(24 小时格式,零填充,00-23) | 14 |
| %I | 小时(12 小时格式,零填充,01-12) | 02 |
| %p | 上午/下午标记(取决于区域设置) | 下午 |
| %M | 分钟(零填充,00-59) | 05 |
| %S | 秒(零填充,00-59) | 07 |
| %f | 微秒(零填充,000000-999999) | 123456 |
| %z | UTC 偏移(±HHMM[SS[.ffffff]] 格式,朴素时间为“空”) | +0100 |
| %Z | 时区名称(朴素时间为“空”) | CET |
| %j | 一年中的第几天(零填充,001-366) | 040 |
| %U | 周数(星期日作为一周的开始,00-53) | 06 |
| %W | 周数(星期一作为一周的开始,00-53) | 06 |
| %V | ISO 8601 周数(01-53) | 07 |
| %G | ISO 8601 基于周的年份 (0000-9999) | 2025 |
| %c | 区域设置的完整日期和时间表示 | 2025 年 2 月 15 日星期二 14:30:45 |
| %x | 区域设置的日期格式 | 02/15/25 |
| %X | 区域设置的时间格式 | 14:30:45 |
| %% | 字面量 % 字符 | % |
使用这些格式说明符,您可以自定义 datetime 输出以满足各种用例,例如日志记录、报告和本地化。Python 的 f-string 提供了一种在格式化字符串中动态应用这些说明符的便捷方法。
使用 f-string 进行基本的 datetime 格式化
使用 f-string 格式化 datetime 对象的最简单方法是使用默认的字符串表示。这将以 ISO 格式显示日期和时间。下面的示例演示了基本格式化。
from datetime import datetime
now = datetime.now()
print(f"Current datetime: {now}")
print(f"Date only: {now:%Y-%m-%d}")
print(f"Time only: {now:%H:%M:%S}")
此代码显示了三种不同的 f-string 格式。第一个使用默认字符串表示。第二个仅格式化日期部分。第三个仅格式化时间部分。冒号后面的格式说明符定义了输出格式。
$ python main.py Current datetime: 2025-02-15 14:30:45.123456 Date only: 2025-02-15 Time only: 14:30:45
使用 f-string 自定义日期格式
f-string 允许对 datetime 格式化进行完全控制。您可以组合任何有效的格式代码来创建自定义日期和时间显示。该示例显示了几个常见的格式选项。
from datetime import datetime
now = datetime.now()
print(f"Full month name: {now:%B %d, %Y}")
print(f"Short month name: {now:%b %d, %Y}")
print(f"Weekday name: {now:%A, %B %d}")
print(f"12-hour clock: {now:%I:%M %p}")
此示例演示了不同的日期和时间格式选项。%B 显示完整的月份名称,%b 显示缩写的月份名称。%A 显示完整的星期名称。%I 使用 %p 进行上午/下午格式化 12 小时制的小时。
$ python main.py Full month name: February 15, 2025 Short month name: Feb 15, 2025 Weekday name: Saturday, February 15 12-hour clock: 02:30 PM
单独格式化 datetime 组件
您可以直接在 f-string 中访问 datetime 对象的各个组件。当您需要将日期部分与其他文本组合时,这提供了灵活性。该示例显示了如何单独格式化组件。
from datetime import datetime
now = datetime.now()
print(f"Today is {now.year}/{now.month:02d}/{now.day:02d}")
print(f"The time is {now.hour:02d}:{now.minute:02d}:{now.second:02d}")
print(f"Day of year: {now.timetuple().tm_yday}")
print(f"Week number: {now.isocalendar().week}")
此代码直接访问年、月和日属性。:02d 格式确保了两位数的格式化,并带有前导零。我们还使用额外的 datetime 方法显示了年份中的第几天和周数。
$ python main.py Today is 2025/02/15 The time is 14:30:45 Day of year: 46 Week number: 7
将 datetime 与其他变量结合使用
f-string 可以轻松地将 datetime 格式化与其他变量结合使用。您可以将日期格式与文本和其他变量值混合。此示例显示了几种组合。
from datetime import datetime
now = datetime.now()
user = "John"
items = 3
total = 45.50
print(f"Receipt for {user} on {now:%Y-%m-%d %H:%M}")
print(f"Order #{12345:06d} - {now:%A %B %d}")
print(f"{items} items purchased for ${total:.2f} at {now:%I:%M %p}")
此示例将 datetime 格式与字符串变量、整数和浮点数结合起来。f-string 会自动将所有值转换为字符串。数字格式(:06d 用于零填充整数,:.2f 用于货币)与 datetime 格式化一起工作。
$ python main.py Receipt for John on 2025-02-15 14:30 Order #012345 - Saturday February 15 3 items purchased for $45.50 at 02:30 PM
格式化 timedelta 对象
Timedelta 对象表示持续时间,也可以使用 f-string 进行格式化。这对于显示时间差或经过时间很有用。该示例显示了几个格式选项。
from datetime import datetime, timedelta
start = datetime(2025, 2, 15, 9, 0)
end = datetime.now()
duration = end - start
print(f"Elapsed time: {duration}")
print(f"Hours: {duration.total_seconds()/3600:.1f}")
print(f"Working time: {duration.seconds//3600}h {(duration.seconds%3600)//60}m")
print(f"Days: {duration.days}, Seconds: {duration.seconds}")
此代码计算两个 datetime 对象之间的时间差。我们显示原始 timedelta、总小时数、格式化的小时和分钟,以及对各个组件的访问。请注意 total_seconds() 和 seconds 属性之间的区别。
$ python main.py Elapsed time: 5:30:45.123456 Hours: 5.5 Working time: 5h 30m Days: 0, Seconds: 19845
区分区域设置的 datetime 格式化
对于国际应用程序,您可能需要特定区域设置的格式。虽然 f-string 不直接支持区域设置,但您可以将它们与 strftime 结合使用。此示例显示了区分区域设置的格式。
from datetime import datetime
import locale
now = datetime.now()
# Set to German locale
locale.setlocale(locale.LC_TIME, 'de_DE')
print(f"German format: {now:%A, %d. %B %Y}")
# Set to French locale
locale.setlocale(locale.LC_TIME, 'fr_FR')
print(f"French format: {now:%A %d %B %Y}")
# Reset to default
locale.setlocale(locale.LC_TIME, '')
print(f"Local format: {now:%x %X}")
此示例演示了特定区域设置的日期格式。locale 模块会更改月份和日名称的显示方式。%x 和 %X 是特定区域设置的日期和时间格式。请注意,区域设置的可用性取决于系统。
$ python main.py German format: Samstag, 15. Februar 2025 French format: samedi 15 février 2025 Local format: 02/15/2025 02:30:45 PM
时区感知的 datetime 格式化
在处理时区时,f-string 可以格式化感知的 datetime 对象。此示例使用 zoneinfo 模块(Python 3.9+)进行时区处理。
from datetime import datetime
from zoneinfo import ZoneInfo
utc_time = datetime.now(ZoneInfo('UTC'))
ny_time = utc_time.astimezone(ZoneInfo('America/New_York'))
tokyo_time = utc_time.astimezone(ZoneInfo('Asia/Tokyo'))
print(f"UTC: {utc_time:%Y-%m-%d %H:%M %Z}")
print(f"New York: {ny_time:%Y-%m-%d %I:%M %p %Z}")
print(f"Tokyo: {tokyo_time:%Y年%m月%d日 %H時%M分}")
此代码显示了同一时刻在三个不同时区的情况。每个 f-string 都包含时区缩写 (%Z)。东京的格式演示了如何将 f-string 与格式说明符中的非 ASCII 字符一起使用。
$ python main.py UTC: 2025-02-15 14:30 UTC New York: 2025-02-15 09:30 AM EST Tokyo: 2025年02月15日 23時30分
在日志消息中格式化 datetime
f-string 在将时间戳包含在日志消息中时特别有用。此示例显示了如何使用 datetime 创建格式化的日志条目。
from datetime import datetime
def log_message(level, message):
now = datetime.now()
print(f"[{now:%Y-%m-%d %H:%M:%S.%f}] [{level.upper():<7}] {message}")
log_message("info", "System started")
log_message("warning", "Low disk space")
log_message("error", "Connection failed")
此日志记录函数使用 f-string 来格式化一致的日志消息。时间戳包含微秒 (%f)。日志级别左对齐并填充到 7 个字符。这可以产生整齐对齐的日志输出。
$ python main.py [2025-02-15 14:30:45.123456] [INFO ] System started [2025-02-15 14:30:45.123456] [WARNING] Low disk space [2025-02-15 14:30:45.123456] [ERROR ] Connection failed
使用条件语句进行高级 datetime 格式化
f-string 可以包含条件表达式以实现动态格式化。此示例显示如何根据 datetime 值更改格式。
from datetime import datetime, time
now = datetime.now()
current_time = now.time()
greeting = (
f"Good {'morning' if time(5,0) <= current_time < time(12,0) else 'afternoon' "
f"if time(12,0) <= current_time < time(18,0) else 'evening'}"
)
print(f"{greeting}! It's {now:%A, %B %d}")
print(f"{'🌞' if current_time.hour < 18 else '🌜'} {now:%I:%M %p}")
此代码根据一天中的时间确定适当的问候语。它在 f-string 中使用嵌套的条件表达式。第二行根据白天或晚上显示表情符号。
$ python main.py Good afternoon! It's Saturday, February 15 🌞 02:30 PM
在数据结构中格式化 datetime
在列表或字典中格式化 datetime 对象时,f-string 的效果很好。此示例显示了在循环中格式化多个日期。
from datetime import datetime, timedelta
today = datetime.now()
dates = [today + timedelta(days=i) for i in range(-2, 3)]
print("Upcoming dates:")
for date in dates:
print(f"- {date:%a %b %d}: {'Past' if date < today else 'Today' if date == today else 'Future'}")
events = {
"Meeting": today.replace(hour=14, minute=0),
"Deadline": today + timedelta(days=2),
"Reminder": today.replace(hour=9, minute=0) + timedelta(days=1)
}
print("\nEvents:")
for name, when in events.items():
print(f"{name:<10} {when:%Y-%m-%d %I:%M %p} ({'Today' if when.date() == today.date() else when.strftime('%A')})")
此示例演示了循环和字典中的 datetime 格式化。第一部分显示了相对日期描述。第二部分根据事件是否是今天,使用不同的 datetime 格式来格式化事件。
$ python main.py Upcoming dates: - Thu Feb 13: Past - Fri Feb 14: Past - Sat Feb 15: Today - Sun Feb 16: Future - Mon Feb 17: Future Events: Meeting 2025-02-15 02:00 PM (Today) Deadline 2025-02-17 02:30 PM (Monday) Reminder 2025-02-16 09:00 AM (Sunday)
解析日期字符串和格式化
通常,您会收到字符串格式的日期,并且需要在格式化它们之前将它们转换为 datetime 对象。Python 的 datetime.strptime() 方法用于此解析。解析后,您可以使用 f-string 来格式化 datetime 对象。
from datetime import datetime
date_string = "2024-07-26 10:30:00"
dt_object = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(f"Parsed datetime: {dt_object}")
print(f"Formatted date: {dt_object:%A, %B %d, %Y}")
print(f"Formatted time: {dt_object:%I:%M %p}")
another_date_string = "15/Mar/2023"
dt_object_date_only = datetime.strptime(another_date_string, "%d/%b/%Y").date()
print(f"Parsed date object: {dt_object_date_only}")
print(f"Formatted: {dt_object_date_only:%d %B, %Y}")
第一个示例解析一个完整的 datetime 字符串,第二个示例将一个字符串解析为 date 对象。strptime 需要一个与输入字符串结构匹配的格式字符串。
$ python main.py Parsed datetime: 2024-07-26 10:30:00 Formatted date: Friday, July 26, 2024 Formatted time: 10:30 AM Parsed date object: 2023-03-15 Formatted: 15 March, 2023
格式化日期和时间对象
datetime 模块还提供了单独的 date 和 time 对象。如果只需要处理日期或时间,可以独立创建和格式化这些对象。f-string 也能很好地处理这些对象。
from datetime import date, time
today_date = date(2025, 8, 15)
specific_time = time(16, 45, 30)
print(f"Date: {today_date:%A, %d %B %Y}")
print(f"ISO Date: {today_date:%Y-%m-%d}")
print(f"Time: {specific_time:%I:%M:%S %p}")
print(f"24-hour Time: {specific_time:%H.%M}")
此示例显示了创建特定的 date 和 time 对象,并使用各种 f-string 指令对其进行格式化。
$ python main.py Date: Friday, 15 August 2025 ISO Date: 2025-08-15 Time: 04:45:30 PM 24-hour Time: 16.45
处理 Unix 时间戳
Unix 时间戳(自纪元(1970 年 1 月 1 日 UTC)以来的秒数)是表示时间的常用方法。Python 的 datetime 模块可以将时间戳转换为 datetime 对象,反之亦然。然后可以使用 f-string 对这些 datetime 对象进行格式化。
from datetime import datetime
timestamp = 1678886400 # Represents 2023-03-15 12:00:00 UTC
# Convert timestamp to datetime object (UTC)
dt_object_utc = datetime.utcfromtimestamp(timestamp)
# For local time, use fromtimestamp()
dt_object_local = datetime.fromtimestamp(timestamp)
print(f"UTC from timestamp: {dt_object_utc:%Y-%m-%d %H:%M:%S %Z}")
print(f"Local from timestamp: {dt_object_local:%Y-%m-%d %H:%M:%S %Z%z}") # %Z%z for timezone info
# Convert datetime object back to timestamp
now = datetime.now()
current_timestamp = now.timestamp()
print(f"Current datetime: {now:%Y-%m-%d %H:%M:%S}")
print(f"Current timestamp: {current_timestamp}")
此代码演示了将 Unix 时间戳转换为 datetime 对象(UTC 和本地时间),然后对其进行格式化。它还显示了将当前 datetime 对象转换回时间戳。请注意,在某些系统上,朴素对象的 %Z 可能会为空;为了完整显示时区名称,最好使用时区感知的对象。
$ python main.py UTC from timestamp: 2023-03-15 12:00:00 UTC Local from timestamp: 2023-03-15 13:00:00 CET+0100 Current datetime: 2025-02-15 14:30:45 Current timestamp: 1739629845.123456
来源
本教程展示了使用 Python f-string 格式化 datetime 对象的各种方法。f-string 提供了一种干净、易读的 datetime 格式化语法,通常比传统方法更直观。
作者
列出所有 Python 教程。