如何在 Python 中处理时区

2024 年 08 月 29 日 | 阅读 9 分钟

在本教程中,我们将定义如何在 Python 中处理不同的时区。我们还将了解 Python 的本地时区。时区可以描述为遵守标准时间的地理区域。让我们对时区进行简要介绍。我们将使用 Python 的 pytz 库来处理时区。

什么是时区?

时区被定义为取决于该地点地理表示的标准时间。换句话说,时区是指基于地球自转的特定区域的本地时间。它以 UTC(协调世界时)定义,这是世界区域时间所依据的标准。

注意 - 建议使用 UTC 作为基础时区。

例如 - 新加坡的 UTC 比印度或北部时区早 2.5 小时,比北部时区早 5 或 6 小时,并根据夏令时表示为 UTC-5 或 UTC-6。让我们看一下以下世界各地不同时区的表格。

Python pytz 库

Python pytz 将 Olson tz 数据库集成到 Python 中,并支持几乎所有时区。该模块允许我们进行日期-时间转换功能,并为客户提供国际化基础。我们还可以根据项目需求执行计算,还可以创建时区感知的 datetime 实例。它还可以解决夏令时结束时模糊时间的问题。

安装

我们需要在系统中安装它才能使用时区。我们可以使用以下命令进行安装。

上面的命令将在您的计算机上安装 pytz。建议在虚拟环境中安装。

Python 附带 DateTime.tzinfo() 抽象基类。此类允许我们处理时区。但直接实例化它并不是一个好习惯。要获取有关特定时区的信息,我们需要创建 DateTime.tzinfo() 的子类。

pytz 库克服了这些缺点,它实现了时区类,用于处理与时区和 UTC 的任意固定偏移量。

例如 - 要在 Python 中获取当前时间,我们使用 datetime.now() 函数。但是,此方法不返回任何时区。使用时区,我们可以将时区传递给此函数,它将返回给定时区的当前 datetime。

pytz 属性

pytz 提供了三个属性和方法来在 Python 中处理时区。

  • pytz.utc
  • pytz.timezone('region')
  • pytz.astimezone()

如何获取当前时间?

要获取当前时间,我们使用 time 模块。我们可以使用 time 模块的以下函数。

  • localtime()- 它允许获取当前的本地时间。
  • strftime("%H:%M:%S", t)- 它允许定义用于显示时间的格式。

示例 -

输出

The current timezone is: 21:22:41

我们获取当前区域的时区和标准 UTC。

创建时区朴素 Datetime 对象

在 Python 中,可以定义带有时区或不带时区的数据对象。此对象也称为 Aware 或 Naïve。如果它包含时区值,则它是一个 Aware Datetime 对象;否则,它默认是 Naïve 对象。

在 Python 中,可以定义带有时区或不带时区的数据对象。此对象也称为 Aware 或 Naïve。如果它包含时区值,则它是一个 Aware Datetime 对象;否则,它默认是 Naïve 对象。

让我们通过以下示例来理解创建时区对象。

示例 -

输出

Timezone naive: 2022-05-08 11:38:01.362134
Timezone Aware: 2022-05-08 06:08:01.363137+00:00
US Central DateTime 2022-05-08 01:08:11.323668-05:00

解释 -

在上面的代码中,我们将 pytz.utc 用作 datetime.now() 函数的参数。末尾的偏移量为 +0.00,这是标准的 UTC 偏移量。在另一行中,我们使用 'US/Central' 区域来创建时区。末尾的偏移量 -05:00 是 CDT 区域的 UTC 偏移量。

pytz 库有大量的时区列表,我们可以使用以下代码打印时区。

输出

['Africa/Abidjan', 'Africa/Accra', 'Africa/Addis_Ababa', 'Africa/Algiers', 'Africa/Asmara', 'Africa/Asmera', 'Africa/Bamako', 'Africa/Bangui', 'Africa/Banjul', 'Africa/Bissau', 'Africa/Blantyre', 'Africa/Brazzaville', 'Africa/Bujumbura', 'Africa/Cairo', 'Africa/Casablanca', 'Africa/Ceuta', 'Africa/Conakry', 'Africa/Dakar', 'Africa/Dar_es_Salaam', 'Africa/Djibouti', 'Africa/Douala', 'Africa/El_Aaiun', 'Africa/Freetown', 'Africa/Gaborone', 'Africa/Harare', 'Africa/Johannesburg', 'Africa/Juba', 'Africa/Kampala', 'Africa/Khartoum', 'Africa/Kigali', 'Africa/Kinshasa', 
'Canada/Pacific', 'Canada/Saskatchewan', 'Canada/Yukon', 'Chile/Continental', 'Chile/EasterIsland', 'Cuba', 'EET', 'EST', 'EST5EDT', 'Egypt', 'Eire', 'Etc/GMT', 'Etc/GMT+0', 'Etc/GMT+1', 'Etc/GMT+10', 'Etc/GMT+11', 'Etc/GMT+12', 'Etc/GMT+2', 'Etc/GMT+3', 'Etc/GMT+4', 'Etc/GMT+5', 'Etc/GMT+6', 'Etc/GMT+7', 'Etc/GMT+8', 'Etc/GMT+9', 'Etc/GMT-0', 'Etc/GMT-1', 'Etc/GMT-10', 'Etc/GMT-11', 'Etc/GMT-12', 'Etc/GMT-13', 'Etc/GMT-14', 'Etc/GMT-2', 'Etc/GMT-3', 'Etc/GMT-4', 'Etc/GMT-5', 'Etc/GMT-6', 'Etc/GMT-7', 'Etc/GMT-8', 'Etc/GMT-9', 'Etc/GMT0', 'Etc/Greenwich', 'Etc/UCT', 'Etc/UTC', 'Etc/Universal', 'Etc/Zulu', 'Europe/Amsterdam', 'Europe/Andorra', 'Europe/Astrakhan', 'Europe/Athens', 'Europe/Belfast', 'Europe/Belgrade', 'Europe/Berlin', 'Europe/Bratislava', 'Europe/Brussels', 'Europe/Bucharest', 'Europe/Budapest', 'Europe/Busingen', 'Europe/Chisinau', 'Europe/Copenhagen', 'Europe/Dublin', 'Europe/Gibraltar', 'Europe/Guernsey', 'Europe/Helsinki', 'Europe/Isle_of_Man', 'Europe/Istanbul', 'Europe/Jersey', 'Europe/Kaliningrad', 'Europe/Kiev', 'Europe/Kirov', 'Europe/Lisbon', 'Europe/Ljubljana', 'Europe/London', 'Europe/Luxembourg', 'Europe/Madrid', 'Europe/Malta', 'Europe/Mariehamn', 'Europe/Minsk', 'Europe/Monaco', 'Europe/Moscow', 'Europe/Nicosia', 'Europe/Oslo', 'Europe/Paris', 'Europe/Podgorica', 'Europe/Prague', 'Europe/Riga', 'Europe/Rome', 'Europe/Samara', 'Europe/San_Marino', 'Europe/Sarajevo', 'Europe/Saratov', 'Europe/Simferopol', 'Europe/Skopje', 'Europe/Sofia', 'Europe/Stockholm', 'Europe/Tallinn', 'Europe/Tirane', 'Europe/Tiraspol', 'Europe/Ulyanovsk', 'Europe/Uzhgorod', 'Europe/Vaduz', 'Europe/Vatican', 'Europe/Vienna', 'Europe/Vilnius', 'Europe/Volgograd', 'Europe/Warsaw', 'Europe/Zagreb', 'Europe/Zaporozhye', 'Europe/Zurich', 'GB', 'GB-Eire', 'GMT', 'GMT+0', 'GMT-0', 'GMT0', 'Greenwich', 'HST', 'Hongkong', 'Iceland', 'Indian/Antananarivo', 'Indian/Chagos', 'Indian/Christmas', 'Indian/Cocos', 'Indian/Comoro', 'Indian/Kerguelen', 'Indian/Mahe', 'Indian/Maldives', 'Indian/Mauritius', 'Indian/Mayotte', 'Indian/Reunion', 'Iran', 'Israel', 'Jamaica', 'Japan', 'Kwajalein', 'Libya', 'MET', 'MST', 'MST7MDT', 'Mexico/BajaNorte', 'Mexico/BajaSur', 'Mexico/General', 'NZ', 'NZ-CHAT', 'Navajo', 'PRC',..............
'Pacific/Efate', 'Pacific/Enderbury', 'Pacific/Fakaofo', 'Pacific/Fiji', 'Pacific/Funafuti', 'Pacific/Galapagos', 'Pacific/Gambier', 'Pacific/Guadalcanal', 'Pacific/Guam', 'Pacific/Honolulu', 'Pacific/Johnston', 'Pacific/Kiritimati', 'Pacific/Kosrae', 'Pacific/Kwajalein', 'Pacific/Majuro', 'Pacific/Marquesas', 'Pacific/Midway', 'Pacific/Nauru', 'Pacific/Niue', 'Pacific/Norfolk', 'Pacific/Noumea', 'Pacific/Pago_Pago', 'Pacific/Palau', 'Pacific/Pitcairn', 'Pacific/Pohnpei', 'Pacific/Ponape', 'Pacific/Port_Moresby', 'Pacific/Rarotonga', 'Pacific/Saipan', 'Pacific/Samoa', 'Pacific/Tahiti', 'Pacific/Tarawa', 'Pacific/Tongatapu', 'Pacific/Truk', 'Pacific/Wake', 'Pacific/Wallis', 'Pacific/Yap', 'Poland', 'Portugal', 'ROC', 'ROK', 'Singapore', 'Turkey', 'UCT', 'US/Alaska', 'US/Aleutian', 'US/Arizona', 'US/Central', 'US/East-Indiana', 
'US/Eastern', 'US/Hawaii', 'US/Indiana-Starke', 'US/Michigan', 'US/Mountain', 'US/Pacific', 'US/Samoa', 'UTC', 'Universal', 'W-SU', 'WET', 'Zulu']

获取不同时区的当前时间

pytz 模块允许我们使用以下方法获取任何时区的当前日期和时间。

语法 -

首先,我们使用 pytz.timezone('region name') 函数创建时区对象,然后将此对象传递给 datetime.now(timezone_obj) 以获取给定时区的当前 datetime。

使用上面的时区列表,我们将获得各种时区的当前时间。

示例 - 1

输出

US Buenos DateTime: 2022:05:08 03:52:13 -03 -0300
US Adak timezone DateTime: 2022:05:07 21:52:13 HDT -0900
US Eastern timezone DateTime: 2022:05:07 22:52:13 AKDT -0800
US Michigan timezone DateTime: 2022:05:08 02:52:13 EDT -0400
US Belam timezone DateTime: 2022:05:08 03:52:13 -03 -0300

解释 -

在上面的代码中,我们获取了美洲不同地区的当前时间。

示例 2:获取不同国家/地区的时间

输出

Israel DateTime: 2022:05:08 10:16:46 IDT +0300
Rome DateTime: 2022:05:08 09:16:46 CEST +0200
Amsterdam DateTime: 2022:05:08 09:16:46 CEST +0200
Hongkong DateTime: 2022:05:08 15:16:46 HKT +0800
Jamaica DateTime: 2022:05:08 02:16:46 EST -0500
Turkey: DateTime: 2022:05:08 10:16:46 +03 +0300

运行代码时,它会返回各个国家/地区的当前时区。

使用 tzinfo 获取时区信息

使用 DateTime.tzinfo 类,我们可以获取有关日期或时间的信息。tzinfo 通常包含以下信息。

  • datetime 的时区。
  • 夏令时
  • 与 UTC 的偏移量。

tzinfo 类是一个抽象类,它提供了以下方法来获取时区信息。

  • utcoffset(dt) - 它返回与 UTC 的总偏移量,它应该是一个 timedelta 对象。如果时间差在 UTC 以东,则时间差值将为正。如果时间差在 UTC 以西,则时间差值将为负。本地时区同时包含时区和 DST 值。因此,时间差的范围是 timedelta 小时 = 24 到 timedelta(小时=24)。
  • tzname(dt) - 此方法返回与 datetime 对象对应的时区名称。
  • dst(dt) - 此方法用于获取 DST 生效区域的 DST 偏移量。如果 DST 无效,则只返回 timedelta(0)。DTC 信息已包含在 UTC 偏移量中。

让我们理解下面的例子。

示例 - 1

输出

Europe London DateTime: 2022:05:08 09:12:09 BST +0100
BST
1:00:00
1:00:00

时区转换

我们可以使用 datetime.astimezone() 方法将 datetime 从一个时区转换为另一个时区。此方法将 datetime 对象作为参数,并返回给定新时区的 datetime。让我们通过以下示例来理解。

示例 -

输出

UTC DateTime: 2022:05:08 08:23:21 UTC +0000
US Hawaii DateTime: 2022:05:07 22:23:21 HST -1000
US Mountain DateTime: 2022:05:07 22:23:21 HST -1000
India DateTime: 2022:05:08 13:53:21 IST +0530

使用本地时区

在上面的部分,我们提到了将朴素 datetime 转换为有感知(aware)的 datetime 实例。我们可以传入设置为本地标准化值的时区值。

pytz 模块提供了 localize() 方法,用于将朴素时间转换为本地时间。它接受参数,即要本地化的 datetime 对象和一个可选的 is_dst 标志。

tzinfo 有一个 dst() 方法,如果标志设置为 true,它将返回夏令时 (DST) 信息。

让我们理解下面的例子。

示例 -

输出

Indian Standard Time:: 2022-05-08 14:28:37 IST+0530
Amsterdam with daylight saving time:: 1997-12-03 02:00:00 CET+0100
Daylight saving time in amsterdam on 3/8/83:: 0:00:00

示例 2:将 UTC 格式转换为 IST 格式

输出

UTC Format                       			IST Format
2022-05-08 09:05:46 UTC +0000     2022-05-08 14:35:46 IST +0530
2022-05-08 09:05:46 UTC +0000     2022-05-08 14:35:46 IST +0530
2022-05-08 09:05:46 UTC +0000     2022-05-08 14:35:46 IST +0530
2022-05-08 09:05:46 UTC +0000     2022-05-08 14:35:46 IST +0530
2022-05-08 09:05:46 UTC +0000     2022-05-08 14:35:46 IST +0530

结论

本教程涵盖了 pytz 库的基本方法。时区在软件开发/Web 开发中起着至关重要的作用,我们讨论了如何获取当前时间和时区。本教程将帮助您熟悉 pytz 库和时区。