Python:datetime tzinfo时区名称文档

42

我有一个我创建的日期:

from datetime import datetime
from datetime import tzinfo
test = '2013-03-27 23:05'
test2 = datetime.strptime(test,'%Y-%m-%d %H:%M')
>>> test2
datetime.datetime(2013, 3, 27, 23, 5)

>>> test2.replace(tzinfo=EST)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'EST' is not defined

>> test2.replace(tzinfo=UTC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'UTC' is not defined

我找不到可以分配给replace.tzinfo=的时区names列表的文档。

我已经阅读了以下内容,但没有发现任何相关信息:

http://docs.python.org/2/library/datetime.html#tzinfo-objects

我也在谷歌上搜索过。

编辑:我按照unutbu提供的解决方案进行操作,但是出现了以下错误:

>>> test = '2013-03-27 00:05'
>>> test
'2013-03-27 00:05'

>>> test2 = dt.datetime.strp(test, '%Y-%m-%d %H:%M')
>>> test2
datetime.datetime(2013, 3, 27, 0, 5)

>>> est = pytz.timezone('US/Eastern')
>>> utc = pytz.utc
>>> print(est.localize(test2))
2013-03-27 00:05:00-04:00
>>> print(utc.localize(test2))
2013-03-27 00:05:00+00:00

>>> print(est.localize(test2,is_dst=False))
2013-03-27 00:05:00-04:00
>>> print(est.localize(test2,is_dst=True))
2013-03-27 00:05:00-04:00
>>>

正如您所看到的,即使我提供了 is_dst= 标志,偏移仍然是“-04:00”,这是EDT而不是EST。感谢您的帮助。谢谢。

文档显示如下:

如果您坚持使用本地时间,该库提供了一种无歧义地构建本地时间的方法: http://pytz.sourceforge.net/#problems-with-localtime

>>> loc_dt = datetime(2002, 10, 27, 1, 30, 00)
>>> est_dt = eastern.localize(loc_dt, is_dst=True)
>>> edt_dt = eastern.localize(loc_dt, is_dst=False)
>>> print(est_dt.strftime(fmt) + ' / ' + edt_dt.strftime(fmt))
2002-10-27 01:30:00 EDT-0400 / 2002-10-27 01:30:00 EST-0500

在文档中早些时候定义了东部时间为eastern = timezone('US/Eastern')

这似乎表明is_dst=标志应进一步指定是否启用夏令时。我需要帮助解决为何在我的情况下无法正常工作。


当我尝试运行这个程序时,出现了一个错误:AttributeError: 'module' object has no attribute 'strptime'。你确定你复制代码的时候没有出错吗? - Moshe
哎呀。你导入了datetime和tzinfo吗?我会编辑我的原帖来包含它们。 - codingknob
我的错,我导入了 datetime,而不是 datetime.datetime。谢谢! - Moshe
4个回答

61

标准库没有定义任何时区 -- 至少不是很好的定义(在文档中给出的玩具示例不能处理像这里提到的那样微妙的问题)。对于预定义的时区,使用第三方pytz模块

import pytz
import datetime as DT

eastern = pytz.timezone('US/Eastern')
utc = pytz.utc
test = '2013-03-27 23:05'

这是一个“朴素”的日期时间:

test2 = DT.datetime.strptime(test, '%Y-%m-%d %H:%M')   
print(test2)
# 2013-03-27 23:05:00

此代码将把test2解释为东部标准时间,并创建一个带有时区的日期时间对象:

print(eastern.localize(test2))
# 2013-03-27 23:05:00-04:00

通过将test2解释为UTC时区,可以创建一个带有时区信息的日期时间:

print(utc.localize(test2))
# 2013-03-27 23:05:00+00:00

另外,您可以使用 astimezone 方法将一个有时区意识的日期时间值转换为另一个时区:

test2_eastern = eastern.localize(test2)
print(test2_eastern.astimezone(utc))
# 2013-03-28 03:05:00+00:00

@unutbu - 谢谢。问题:为什么时间偏移量是“-04:00”?这不应该被视为东部标准时间(EST),而不是东部夏令时(EDT)吗? - codingknob
@algotr8der:夏令时于2013年3月10日凌晨2点开始。因此,在“美国/东部”时区中是EDT。 - unutbu
如果你想无论什么日期都要使用 EST,请使用 pytz.timezone('EST') - unutbu
如果我这样做,它会像预期的那样显示-05:00偏移量。也就是说,当pytz.timezone ='US / Eastern'和pytz.timezone ='EST'时,为什么设置is_dat =标志不起作用。 当我设置timezone ='EST'并包括is_dst = True时,我应该看到-05:00偏移量,当我设置timezone ='US / Eastern'并包括is_dst = False时,我应该看到-04:00偏移量。文档似乎在这里指出:http://pytz.sourceforge.net/#problems-with-localtime。 - codingknob
1
@algotr8der:is_dst参数仅影响localize如何解释模糊日期。(在秋季,你会“倒退”,创建两个时间段,这两个时间段的名称相同)。 - unutbu

29
自从发布了 Python 3.9 版本以来,标准库中已经定义了时区,并且您可以通过以下方式获取它们。
import zoneinfo
print(zoneinfo.available_timezones())

# {'America/Belem', 'Asia/Tel_Aviv', 'Australia/North', 'Asia/Omsk', 
#  'Europe/Isle_of_Man', 'America/New_York', 'Europe/Nicosia', 
#  'Pacific/Funafuti', 'America/Ensenada', 'Europe/Mariehamn', 
#  'America/Maceio', 'America/Guatemala', 'America/Guadeloupe', ...

1
zoneinfo 从操作系统或者在 Windows 上使用 tzdata 获取时区信息。 - Flimm

9

如@FObersteiner所述,在python 3.9版本中,您无需安装第三方pytz,而是可以使用本地的zoneinfo

from datetime import datetime
from zoneinfo import ZoneInfo

test = '2013-03-27 23:05'
test2 = datetime.strptime(test,'%Y-%m-%d %H:%M')
date_string = test2.replace(tzinfo=ZoneInfo('US/Eastern'))
print(datestring)
2013-03-27 23:05:00-04:00

2
 import pytz
 timezones=pytz.all_timezones

这将提供所有时区。

1
你应该提到这是一个独立的依赖项,并讨论为什么要使用它等等。现在Python 3.9有zoneinfo,这一点非常重要。 - LudvigH
这仍然是我在2022年5月问题的最佳答案,因为3.9在发行版中还不是很常见(而且我已经导入了pytz)。 - tsbertalan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接