Python 时区是什么?完整介绍
作者:社区 / 开发者
2024 年 1 月 12 日
导航至
Datetime Python 对象分为两组:朴素型和感知型。朴素型 datetime 对象是不携带任何时区信息的对象,而感知型对象则携带此类信息。考虑到这一点,如果您想有效地使用 Python datetime 对象,您必须了解 Python 时区,而这正是本文的全部内容。
我将首先回答标题问题来开始本文:Python 时区是什么?您将了解 Python 编程中的时区是什么以及它们扮演的角色,并看到一些时区示例。
在了解了 Python 时区的是什么和为什么之后,下一步合乎逻辑的步骤是介绍如何:您将看到如何在实践中开始使用 Python 时区,无论是否使用著名的 pytz 库。在总结之前,您将看到一个简短的问答环节,其中包含人们关于 Python 时区的一些常见问题。
让我们开始吧!
先决条件
跟随本文学习的先决条件不多。您只需要安装 Python(版本 3.9 或更高版本)并基本熟悉该语言。您具备这些条件吗?那么我们就可以开始了。
Python 时区是什么?
时区到底是什么?以下是 维基百科定义 的开头
时区是为法律、商业和社会目的而遵守统一标准时间的区域。
因此,Python 时区只是 Python 对时区概念的实现。
时区在 Python 编程中的作用
当您需要使用感知型 datetime 对象时,在 Python 编程中使用时区至关重要。正如您在引言中读到的,Python datetime 对象默认是朴素型的——也就是说,它们不知道任何关于时区的信息。请看以下代码片段
from datetime import datetime
today = datetime.now()
print(today)
print(today.tzinfo)
上面的代码使用 datetime.now()
函数检索当前日期和时间并显示它。此外,它还显示 datetime 对象上 tzinfo 属性的值。
但是,您从 datetime.now()
获取的 datetime 对象是一个朴素型对象:它不知道其来源的时区。看看我在打印后得到的结果
2023-09-30 18:46:45.951525
None
代码显示了当前的——关于本地机器的——日期和时间,但对象不知道它所属的时区:这就是为什么显示 None。
现在,让我们尝试一些不同的东西:从特定时区检索 datetime。首先,让我们安装一个必需的软件包
pip install tzdata
tzdata 软件包包含我们将在接下来的代码示例中需要使用的时区数据。好的,下一步实际上是将之前的代码更改为以下代码
from zoneinfo import ZoneInfo
from datetime import datetime
today = datetime.now(ZoneInfo("America/Los_Angeles"))
print(today)
print(today.tzinfo)
事情开始变得有趣起来,对吧?正如您所看到的,代码现在为 datetime.now()
函数提供了 ZoneInfo 类的实例,指定 “America/Los_Angeles” 作为时区。
通过运行代码,这是我现在得到的结果
2023-09-30 14:59:34.788621-07:00
America/Los_Angeles
现在看起来不一样了。以 ISO-8601 格式显示日期和时间的字符串现在包含附加到它的 UTC 偏移量(“-07:00”)。此外,对象上的 tzinfo 属性现在正确返回时区的名称。
Python 时区示例
在 Python 中——以及在一般编程中——使用时区时,您通常会看到时区由如下字符串表示
- America/Sao_Paulo
- Europe/Lisbon
- Asia/Tokyo
这些到底是什么,它们是如何工作的?
以上是来自 tz 数据库(也称为 IANA 时区数据库或 Olson 数据库)的唯一时区名称示例。
如何使用 Python 时区
您已经看到了如何在 Python 编程中使用时区的一瞥。现在让我们深入研究它。正如您在本文中看到的——并且可能之前已经意识到的——Python 提供了 datetime 模块,该模块存储了许多您需要用于处理日期的类型和函数。
您现在将看到两种可以用来检索感知其时区的对象的方法
- 使用流行的 pytz 库
- 仅使用原生功能
pytz 库
pytz 库是一个库,使 Python 程序员能够处理来自 Olson 数据库 的时区。让我们看一个使用示例。首先,您需要安装依赖项
pip install pytz
然后,编写一些代码
from datetime import datetime
import pytz
# getting the timezone for Santiago, Chile
chile_timezone = pytz.timezone("America/Santiago")
# retrieving the current time according to the timezone
current_time = datetime.now(chile_timezone)
print(current_time)
原生方法
自 3.9 版本以来,Python 计算了 zoneinfo 模块,您已经在之前的示例中熟悉了它。让我们将之前的 pytz 示例转换为 zoneinfo
from datetime import datetime
from zoneinfo import ZoneInfo
# Getting the timezone for Santiago, Chile
chile_timezone = ZoneInfo("America/Santiago")
# Retrieving the current time according to the timezone
current_time = datetime.now(chile_timezone)
print(current_time)
从大局来看,代码并没有发生太大变化,那么您应该选择哪一个呢?您将在稍后了解更多关于这方面的信息。
Python 时区问答
让我们快速回顾一下。到目前为止,您已经学习了
- Python 中的时区是什么,以及它们为什么重要
- 一些重要时区的列表,以及在 tz(又名 Olson)数据库中标识它们的字符串
- 如何使用 Python 时区,通过两种不同的方法
现在,让我们通过回答常见的 Python 时区问题来涵盖更多内容。
如何在 Python 中获取时区?
正如您从我们的示例中看到的那样,您可以通过使用 pytz 库或较新的 zoneinfo 模块来获取时区
# Getting the timezone for Santiago, Chile using 'ZoneInfo'
chile_timezone = ZoneInfo("America/Santiago")
# Getting the timezone for Santiago, Chile using 'pytz'
chile_timezone = pytz.timezone("America/Santiago")
您应该选择哪一个?下一个问题将回答这个问题。
pytz 已弃用吗?
在撰写本文时(2023 年末):是的, pytz 已弃用。 根据该项目的 主页,您不应将其用于使用 Python 3.9 或更新版本编写的新项目
使用 Python 3.9 或更高版本的项目应使用现在作为标准库一部分包含的支持,并且第三方软件包可以与其一起使用,例如 tzdata。pytz 除了与为早期版本的 Python 编写的代码向后兼容之外,没有提供任何优势。
Python 使用哪个库来处理时区?
从历史上看,Python 用于时区处理的主要软件包是,正如您所看到的,pytz。并且,正如您也看到的那样,此软件包目前已弃用,这意味着使用最新版本的语言编写程序的 Python 开发者应首选使用 zoneinfo 模块的新原生解决方案。
在本文的开头,我们使用了另一个库:tzdata。此软件包包含时区数据库的实际数据。有趣的是,您并不总是需要该软件包:它的目的是充当没有此数据(咳嗽,Windows,咳嗽)或可能在标准位置没有此数据的系统的后备。
总结和最佳实践
时间处理是一个引人入胜且复杂的主题。在本文中,您了解了 Python 中的时区、它们的重要性以及如何使用它们。在告别之前,我将分享一些技巧。首先,每当您需要记录在给定时间发生的事情时(例如,用于日志记录或审计目的),请使用 UTC。这是一个例子
utc_timezone = zoneinfo.ZoneInfo("UTC")
utc_time = datetime.now(utc_timezone)
当日期不需要离开单台机器的上下文时,本地/朴素型 datetime 非常棒——例如,它们将仅用于在屏幕上显示。一旦它们被“传输”——例如,通过网络发送或持久化到数据库——所有上下文都将丢失。
当然,在执行 比较 和计算时,请避免混合使用朴素型和感知型对象。此外,在执行时间算术时要谨慎。如果您不注意(例如)夏令时,则可能会获得不正确的结果。
最后,始终努力教育您的团队了解日期和时间的基础知识。这个主题很棘手——开发者并不总是受过这方面的教育,并且许多编程语言的日期和时间 API 都是以容易出错的方式编写的。
其他资源
本文由 Carlos Schults 撰写。Carlos 是一名顾问和软件工程师,在桌面、Web 和移动开发方面拥有经验。虽然他的主要语言是 C#,但他拥有多种语言和平台的经验。他的主要兴趣包括自动化测试、版本控制和代码质量。