如何在Python中处理时区
在本教程中,我们将定义如何在Python中处理不同的时区。我们还将了解Python的本地时区。时区可以被描述为观察到标准时间的地理区域。让我们简要介绍一下时区。我们将使用Python的pytz库来处理时区。
什么是时区
时区是根据该地地理表示而定义的标准时间。换句话说,时区是指基于地球自转的特定地区的当地时间。它以世界各地基于区域的时间协调的标准时间UTC(协调世界时)来定义。
注意-建议您使用UTC作为基本时区
例如- 新加坡的UTC比印度提前2.5小时,也比北方的时区提前5或6小时,分别表示为UTC-5或UTC-6,取决于夏令时。让我们看一下世界各地的不同时区的下表。
Python pytz库
Python的 pytz 库将Olson tz 数据库引入Python,并支持几乎所有时区。这个模块允许我们使用日期时间转换功能,并为国际客户提供服务。我们还可以根据项目需求进行计算,并创建时区感知的日期时间实例。它还可以解决在夏令时结束时的时间模糊问题。
安装
我们需要在系统中安装它以处理时区。我们可以使用以下命令进行安装。
pip install pytz
以上命令将在您的计算机上安装pytz。建议在虚拟环境中安装。
Python附带了DateTime.tzinfo()抽象基类。该类允许我们处理时区。但直接实例化不是一个好的实践。要获取有关特定时区的信息,我们需要创建DateTime.tzinfo()的子类。
pytz库克服了这些缺点,它实现了一个时区类,可以处理任意固定偏移的时区和UTC。
例如- 要在Python中获取当前时间,我们使用datetime.now()函数。但是,此方法不返回任何时区。使用时区,我们可以将时区传递给此函数,它将返回给定时区的当前日期时间。
pytz属性
pytz提供了三个属性和方法,用于在Python中处理时区。
- pytz.utc
- pytz.timezone(‘region’)
- pytz.astimezone()
如何获取当前时间
要获取当前时间,我们使用time模块。我们可以使用time模块的以下函数。
- localtime() - 它可以获取当前的本地时间。
- strftime(“%H:%M:%S”, t) - 它允许定义用于显示时间的时间格式。
示例
import time
current_time = time.localtime()
current_clock = time.strftime("%H:%M:%S", current_time)
print("The current timezone is:", current_clock)
输出:
The current timezone is: 21:22:41
我们获取该地区的当前时区和标准的UTC时间。
创建时区非法定时间对象
在Python中,可以定义带有或不带有时区的数据对象。这个对象也被称为Aware或Naïve对象。如果它包含时区值,那么它就是一个有意识的
在Python中,可以定义带有或不带有时区的数据对象。这个对象也被称为Aware或Naïve对象。如果它包含时区值,那么它就是一个有意识的DateTime对象;否则,它默认是一个非法定对象。
让我们来理解一下创建时区对象的以下示例。
示例
from datetime import datetime
import pytz
# Get the current Datetime
unaware_object = datetime.now()
print('Timezone naive:', unaware_object)
# Standard UTC timezone aware Datetime
aware_object = datetime.now(pytz.utc)
print('Timezone Aware:', aware_object)
# US/Central timezone datetime
aware_us_central = datetime.now(pytz.timezone('US/Central'))
print('US Central DateTime', aware_us_central)
输出:
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库中有大量的时区列表,我们可以使用以下代码打印时区。
import pytz
for timezone in pytz.all_timezones:
print(timezone)
输出:
['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模块允许我们使用下面的方法获取任何时区的当前日期和时间。
语法 –
datetime.now(pytz.timezone('timezone name'))
首先,我们使用 pytz.timezone(‘地区名称’) 函数创建时区对象,然后将该对象传递给 datetime.now(timezone_obj) 以获取指定时区的当前日期时间。
使用上述时区列表,我们将获取各个时区的当前时区。
示例1:
from datetime import datetime
import pytz
dt_us_Buenos = datetime.now(pytz.timezone('America/Argentina/Buenos_Aires'))
print("US Buenos DateTime:", dt_us_Buenos.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_us_adak = datetime.now(pytz.timezone('America/Adak'))
print("US Adak timezone DateTime:", dt_us_adak.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_us_anchorage = datetime.now(pytz.timezone('America/Anchorage'))
print("US Eastern timezone DateTime:", dt_us_anchorage.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_us_chihuahua = datetime.datetime.now(pytz.timezone('America/Chihuahua'))
print("US Chihuahua timezone DateTime:", dt_us_chihuahua.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_us_belam = datetime.now(pytz.timezone('America/Belem'))
print("US Belam timezone DateTime:", dt_us_belam.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
输出:
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:获取不同国家的时区
from datetime import datetime
import pytz
dt_israel = datetime.now(pytz.timezone('Israel'))
print("Israel DateTime:", dt_israel.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_rome = datetime.now(pytz.timezone('Europe/Rome'))
print("Rome DateTime:", dt_rome.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_amsterdam = datetime.now(pytz.timezone('Europe/Amsterdam'))
print("Amsterdam DateTime:", dt_amsterdam.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_hongkong = datetime.now(pytz.timezone('Hongkong'))
print("Hongkong DateTime:", dt_hongkong.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_jamaica = datetime.now(pytz.timezone('Jamaica'))
print("Jamaica DateTime:", dt_jamaica.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
dt_turkey = datetime.now(pytz.timezone('Turkey'))
print("Turkey: DateTime:", dt_turkey.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
输出:
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通常包含以下信息:
- 日期时间的时区。
- 夏令时。
- 与UTC的偏移量。
tzinfo类是一个抽象类,该类提供以下方法来获取时区信息:
- utcoffset(dt) – 它返回与UTC的总偏移量,应该是一个时间差对象。如果时间差东于UTC,时间差值将为正数。如果时间差西于UTC,时间差值将为负数。本地时区既有时区又有夏令时值。因此,时间差的范围在timedelta小时=24到timedelta(hours=24)之间。
- tzname(dt) – 该方法返回与datetime对象对应的时区名称。
- utcoffset(dt) – 此方法用于获取夏令时在夏令时生效的区域的偏移量。如果夏令时不生效,它将仅返回 timedelta(0) 。DTC信息已经是UTC偏移量的一部分。
让我们来理解下面的示例。
示例1:
from datetime import datetime
import pytz
# timezone: US Central Time
dt_eur_london = datetime.now(pytz.timezone('Europe/London'))
print("Europe London DateTime:", dt_eur_london.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
# Get current TimeZone name
print(dt_eur_london.tzname())
# Get UTC Offset
print(dt_eur_london.utcoffset())
# Get the daylight saving time (DST offset) adjustment
print(dt_eur_london.dst())
输出:
Europe London DateTime: 2022:05:08 09:12:09 BST +0100
BST
1:00:00
1:00:00
转换时区
我们可以使用datetime.astimezone()方法将一个时区的日期时间转换为另一个时区。该方法接受日期时间对象作为参数,并返回给定时区的新日期时间。让我们理解以下示例。
示例
import datetime
import pytz
# UTC timezone Datetime
dt_local = datetime.datetime.now(pytz.utc)
print("UTC DateTime:", dt_local.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
# convert UTC timezone to 'US/Central'
dt_us_hawaii = dt_local.astimezone(pytz.timezone('US/Hawaii'))
print("US Hawaii DateTime:", dt_us_hawaii.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
# Convert 'US/Mountain' timezone to US/Central
dt_us_central = dt_us_hawaii.astimezone(pytz.timezone('US/Mountain'))
print("US Mountain DateTime:", dt_us_central.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
# Convert US/Central timezone to IST (India) timezone
dt_ind = dt_us_central.astimezone(pytz.timezone('Asia/Kolkata'))
print("India DateTime:", dt_ind.strftime("%Y:%m:%d %H:%M:%S %Z %z"))
输出:
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
使用本地时区
在上一节中,我们提到了将本地时间转换为有意义的时间实例。我们可以将时区值设置为本地标准值。
pytz模块提供了 localize() 方法,用于将本地时间转换为有意义的时间。它接受两个参数,即要本地化的datetime对象和一个可选的 is_dst 标志。
tzinfo 有一个 dst() 方法,如果标志设置为真,则返回夏令时(Daylight Saving Time, DST)信息。
让我们看下面的示例。
示例
from datetime import datetime
import pytz
date_format = '%Y-%m-%d %H:%M:%S %Z%z'
# Indian Standard Time
timezone_ind= pytz.timezone('Asia/Kolkata')
ist_local = timezone_ind.localize(datetime.now())
print("Indian Standard Time::", ist_local.strftime(date_format))
# Europe/Amsterdam Time
amdam_tz = pytz.timezone('Europe/Amsterdam')
dt = datetime(1997, 12, 3, 2, 0, 0)
cest_local = amdam_tz.localize(dt, is_dst=True)
print("Amsterdam with daylight saving time::", cest_local.strftime(date_format))
# Day Light Saving
print("Daylight saving time in amsterdam on 3/8/83::", cest_local.tzinfo.dst(cest_local))
输出:
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格式
from datetime import datetime
import pytz
UTC = pytz.utc
timezone_Kol = pytz.timezone('Asia/Kolkata')
dt_Kl = datetime.now(timezone_Kol)
utc_Kl = dt_Kl.astimezone(UTC)
timezone_New = pytz.timezone('America/New_York')
dt_Ny = datetime.now(timezone_New)
utc_Ny = dt_Ny.astimezone(UTC)
timezone_Mase = pytz.timezone('Africa/Maseru')
dt_Ma = datetime.now(timezone_Mase)
utc_Ma = dt_Ma.astimezone(UTC)
timezone_central = pytz.timezone('US/Central')
dt_Ce = datetime.now(timezone_central)
utc_Ce = dt_Ce.astimezone(UTC)
timezone_athens= pytz.timezone('Europe/Athens')
dt_At = datetime.now(timezone_athens)
utc_At = dt_At.astimezone(UTC)
print("UTC Format \t\t\t IST Format")
print(utc_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'),
"\t ",
dt_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'))
print(utc_Ny.strftime('%Y-%m-%d %H:%M:%S %Z %z'),
"\t ",
dt_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'))
print(utc_Ma.strftime('%Y-%m-%d %H:%M:%S %Z %z'),
"\t ",
dt_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'))
print(utc_Ce.strftime('%Y-%m-%d %H:%M:%S %Z %z'),
"\t ",
dt_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'))
print(utc_At.strftime('%Y-%m-%d %H:%M:%S %Z %z'),
"\t ",
dt_Kl.strftime('%Y-%m-%d %H:%M:%S %Z %z'))
输出:
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库的基本方法。时区在软件开发/网站开发中起着重要作用,我们讨论了如何获取当前时间和时区。这个教程将帮助您熟悉pytz库和时区。