ZetCode

使用 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
%uISO 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
%zUTC 偏移(±HHMM[SS[.ffffff]] 格式,朴素时间为“空”)+0100
%Z时区名称(朴素时间为“空”)CET
%j一年中的第几天(零填充,001-366)040
%U周数(星期日作为一周的开始,00-53)06
%W周数(星期一作为一周的开始,00-53)06
%VISO 8601 周数(01-53)07
%GISO 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 格式显示日期和时间。下面的示例演示了基本格式化。

main.py
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 格式化进行完全控制。您可以组合任何有效的格式代码来创建自定义日期和时间显示。该示例显示了几个常见的格式选项。

main.py
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 对象的各个组件。当您需要将日期部分与其他文本组合时,这提供了灵活性。该示例显示了如何单独格式化组件。

main.py
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 格式化与其他变量结合使用。您可以将日期格式与文本和其他变量值混合。此示例显示了几种组合。

main.py
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 进行格式化。这对于显示时间差或经过时间很有用。该示例显示了几个格式选项。

main.py
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 结合使用。此示例显示了区分区域设置的格式。

main.py
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+)进行时区处理。

main.py
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 创建格式化的日志条目。

main.py
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 值更改格式。

main.py
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 的效果很好。此示例显示了在循环中格式化多个日期。

main.py
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 对象。

main.py
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 模块还提供了单独的 datetime 对象。如果只需要处理日期或时间,可以独立创建和格式化这些对象。f-string 也能很好地处理这些对象。

main.py
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}")

此示例显示了创建特定的 datetime 对象,并使用各种 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 对象进行格式化。

main.py
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 datetime - 文档

本教程展示了使用 Python f-string 格式化 datetime 对象的各种方法。f-string 提供了一种干净、易读的 datetime 格式化语法,通常比传统方法更直观。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Python 教程