Python 使用pytz和UTC转换丢失DST信息

Python 使用pytz和UTC转换丢失DST信息,python,datetime,timezone,utc,pytz,Python,Datetime,Timezone,Utc,Pytz,也许这是一个凌晨4点的错误,但我认为我做的一切都是对的,但看起来DST并没有从UTC时间戳转换为本地化的日期时间 >>从datetime导入datetime >>>进口皮茨 >>>东部=pytz.时区(“美国/东部”) >>>utc=pytz.utc >>>local\u now=eastern.localize(datetime.now()) >>>utc\u now=本地\u now.astimezone(utc) >>>秒=整数(utc_now.strftime(“%s”)) >>>utc

也许这是一个凌晨4点的错误,但我认为我做的一切都是对的,但看起来DST并没有从UTC时间戳转换为本地化的日期时间

>>从datetime导入datetime
>>>进口皮茨
>>>东部=pytz.时区(“美国/东部”)
>>>utc=pytz.utc
>>>local\u now=eastern.localize(datetime.now())
>>>utc\u now=本地\u now.astimezone(utc)
>>>秒=整数(utc_now.strftime(“%s”))
>>>utc\u然后=utc.localize(datetime.fromtimestamp(秒))
>>>本地_then=utc_then.astimezone(东部)
>>>现在打印utc\u,然后打印utc\u
2013-06-16 10:05:27.893005+00:00 2013-06-16 11:05:27+00:00
>>>现在打印本地\u,然后打印本地\u
2013-06-16 06:05:27.893005-04:00 2013-06-16 07:05:27-04:00
当您有时间戳时,要获取UTC中的日期时间,请使用

DT.datetime.utcfromtimestamp(seconds)


注意,
timetuple()
utctimetuple()
方法会使日期时间缩短几微秒。要以保留微秒的方式将日期时间转换为时间戳,请使用。

您应该避免使用
datetime.now
如果您想编写可移植代码,因为它总是使用本地时区,所以
local\u now=eastern。localize(datetime.now())
仅当本地计算机上的时区是东部时才起作用。始终尝试使用
utcnow
,出于同样的原因
utcfromtimestamp

此外,使用strftime(“%s”)将日期时间转换为时间戳也不起作用

from datetime import datetime
import pytz

utc_now = pytz.utc.localize(datetime.utcnow())
eastern = pytz.timezone("US/Eastern")
local_now = utc_now.astimezone(eastern)

# seconds = utc_now.timestamp()  python3
seconds = (utc_now - pytz.utc.localize(datetime.utcfromtimestamp(0))).total_seconds()
utc_then = pytz.utc.localize(datetime.utcfromtimestamp(seconds))

local_then = utc_then.astimezone(eastern)

print("%s - %s" % (utc_now, utc_then))
print("%s - %s" % (local_now, local_then))

要将本地时区设置为
pytz.timezone
对象,可以使用
tzlocal
模块:

#!/usr/bin/env python
from datetime import datetime
import pytz # pip install pytz
from tzlocal import get_localzone # pip install tzlocal

local_tz = get_localzone()
local_now = datetime.now(local_tz)
utc_now = local_now.astimezone(pytz.utc)
seconds = (utc_now - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()

utc_then = datetime.fromtimestamp(seconds, pytz.utc)
local_then = utc_then.astimezone(local_tz)
print("%s %s" % (utc_now, utc_then))
print("%s %s" % (local_now, local_then))
  • 不要使用
    datetime.now()
    ——它可能不明确,例如在DST更改期间。要么像我的示例中那样显式地传递tzinfo,要么使用
    datetime.utcnow()
  • 现在不要使用utc。strftime(“%s”)——它是不可移植的。使用
  • 不要使用
    utc.localize(datetime.fromtimestamp(seconds))
    --
    .fromtimestamp()
    返回本地时区中可能不同于utc的原始日期时间对象。要么像我的示例中那样显式地传递tzinfo,要么使用
    datetime.utcfromtimestamp()
    获取表示UTC时间的原始datetime对象
  • 不要将
    datetime.utctimetuple()
    用于简单的datetime对象——它不会将它们转换为UTC。如果对象已在UTC中:
    UTC\u now.timetuple()
    返回相同的时间
要对不明确的本地时间引发异常,请使用
localize(isdst=None)

如果没有
is_dst=None
,则在dst更改期间,
tz.localize()
返回错误结果的可能性为50%。如果在特定情况下,最好得到一个可能错误的结果,而不是异常,那么您可以传递显式的
is_dst=False
来提醒自己

通常,如果源时区和目标时区都不是UTC,则建议在
.astimezone()
之后调用
tz.normalize()

datetime(1970,1,1,tzinfo=pytz.UTC)
可能比
pytz.UTC.localize(datetime.utcfromtimestamp(0))更明确。
。我不确定stdlib是否能与其他具有划时代价值的软件一起工作。
import datetime as DT
import pytz
import calendar
eastern = pytz.timezone("US/Eastern")
utc = pytz.utc
now = DT.datetime(2013, 6, 16, 10, 0, 0)
local_now = eastern.localize(now)
utc_now = local_now.astimezone(utc)
seconds = calendar.timegm(utc_now.utctimetuple())

print(seconds)
# 1371391200

utc_then = utc.localize(DT.datetime.utcfromtimestamp(seconds))
local_then = utc_then.astimezone(eastern)

print utc_now, utc_then
# 2013-06-16 14:00:00+00:00 2013-06-16 14:00:00+00:00
print local_now, local_then
# 2013-06-16 10:00:00-04:00 2013-06-16 10:00:00-04:00
from datetime import datetime
import pytz

utc_now = pytz.utc.localize(datetime.utcnow())
eastern = pytz.timezone("US/Eastern")
local_now = utc_now.astimezone(eastern)

# seconds = utc_now.timestamp()  python3
seconds = (utc_now - pytz.utc.localize(datetime.utcfromtimestamp(0))).total_seconds()
utc_then = pytz.utc.localize(datetime.utcfromtimestamp(seconds))

local_then = utc_then.astimezone(eastern)

print("%s - %s" % (utc_now, utc_then))
print("%s - %s" % (local_now, local_then))
#!/usr/bin/env python
from datetime import datetime
import pytz # pip install pytz
from tzlocal import get_localzone # pip install tzlocal

local_tz = get_localzone()
local_now = datetime.now(local_tz)
utc_now = local_now.astimezone(pytz.utc)
seconds = (utc_now - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()

utc_then = datetime.fromtimestamp(seconds, pytz.utc)
local_then = utc_then.astimezone(local_tz)
print("%s %s" % (utc_now, utc_then))
print("%s %s" % (local_now, local_then))
aware_dt = tz.localize(naive_dt, is_dst=None)