我有一个应该在EST的时间戳:
2014-10-06T18:06:40-04:56
我理解第一部分:2014-10-06T18:06:40
,但不是-04:56
。
-04:56
在这里意味着什么?`
以下是我获得该时间戳的方法:
import datetime
start_time = datetime.datetime(year = 2014,
month = 10,
day = 6,
hour = 18,
tzinfo = pytz.timezone('US/Eastern'))
end_time = start_time + datetime.timedelta(seconds=400)
然后:
end_time.isoformat()
返回:
2014-10-06T18:06:40-04:56
答案 0 :(得分:20)
问题在于pytz
:
...与用于tzinfo实现的文档化Python API不同;如果要创建本地挂钟时间,则需要使用本文档中记录的
localize()
方法...
进一步向下,它说:
不幸的是,对于许多时区,使用标准日期时间构造函数的tzinfo参数“对pytz不起作用”。
>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
'2002-10-27 12:00:00 LMT+0020'
因此,您需要执行文档建议的内容 - 使用normalize
,构建UTC时间并使用astimezone
等。您想要哪一个取决于您正在尝试做什么。例如:
>>> from datetime import datetime
>>> from pytz import timezone
>>> utc = timezone('UTC')
>>> eastern = timezone('US/Eastern')
>>> datetime(2014, 10, 6, 18, tzinfo=eastern).isoformat()
'2014-10-06T18:00:00-04:56'
>>> eastern.normalize(datetime(2014, 10, 6, 18, tzinfo=eastern)).isoformat()
'2014-10-06T18:56:00-04:00'
>>> datetime(2014, 10, 6, 18, tzinfo=utc).astimezone(eastern).isoformat()
'2014-10-06T14:00:00-04:00'
>>> eastern.localize(datetime(2014, 10, 6, 18)).isoformat()
'2014-10-06T18:00:00-04:00'
我认为这是你想要的最后一次。正如localize
的文档所说:
将天真时间转换为当地时间。
此方法应该用于构造本地时间 而不是将tzinfo参数传递给datetime构造函数。
我认为构建当地时间正是你想要的。
如果您想知道为什么 ......好吧,如果您查看Olson数据库中的数据,或打印出eastern._utcoffset
,您会看到-1天,+ 68640分钟。这是19.0166+小时,而不是19.为什么?因为每个时区都定义了它的起始偏移量,并从那里进行调整。东部是基于纽约的时区截至1883年11月18日12:03:58,此时格林威治标准时间是-04:56:02。从1920年开始的日期调整减去额外的00:03:58。当然,每年为夏令时来回调整一小时。所以,截至目前,东方是-04:00,但不知道它应该代表什么日期,它是-04:56。并且,因为datetime
只是询问一个时区的偏移量,而不是它在特定时间的偏移量,这就是它所得到的。
最后一件事:EST是东部标准时间,即-05:00。这不是2014年10月6日在美国任何地点的时区,因为在2014年,美国的夏令时将持续到11月2日。 (曾经是印第安纳州夏季期间在美国东部时间的县,但不再有。)你要找的是东部日光时间,也就是-04:00。或者,当然,ET,即夏季的EDT和冬季的EST,这是您查找'US/Eastern'
或'America/New_York'
时获得的。
答案 1 :(得分:4)
-04:56在这里是什么意思?`
这意味着生成输入时间戳的代码被打破,这表明对pytz
时区的工作方式缺乏了解。你不应该相信它的结果,如果你认为只有UTC偏移量(-04:56
)是错误的但日期本身是东部时区的正确时间然后解析时间,请执行:
#!/usr/bin/env python
from datetime import datetime, timedelta
import pytz
tz = pytz.timezone('America/New_York')
naive = datetime.strptime("2014-10-06T18:06:40-04:56"[:-6],
"%Y-%m-%dT%H:%M:%S")
start_time = tz.localize(naive, is_dst=None)
end_time = tz.normalize(start_time + timedelta(seconds=400))
print(start_time.isoformat())
print(end_time.isoformat())
tz.localize()
而不是直接分配tzinfo
属性is_dst=None
断言输入时间存在且明确无误tz.normalize()
是必要的2014-10-06T18:06:40-04:00
2014-10-06T18:13:20-04:00
localize()
中描述了为什么需要normalize()
,-04:56
。
2014
UTC偏移在东部时区的>>> import pytz
>>> pytz.timezone('US/Eastern')
{(datetime.timedelta(-1, 72000),
datetime.timedelta(0, 3600),
'EWT'): <DstTzInfo 'US/Eastern' EWT-1 day, 20:00:00 DST>,
(datetime.timedelta(-1, 68640),
datetime.timedelta(0),
'LMT'): <DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>,
(datetime.timedelta(-1, 72000),
datetime.timedelta(0, 3600),
'EDT'): <DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>,
(datetime.timedelta(-1, 68400),
datetime.timedelta(0),
'EST'): <DstTzInfo 'US/Eastern' EST-1 day, 19:00:00 STD>,
(datetime.timedelta(-1, 72000),
datetime.timedelta(0, 3600),
'EPT'): <DstTzInfo 'US/Eastern' EPT-1 day, 20:00:00 DST>}
中错误timedelta(-1, 68640)
请注意LMT tzinfo的UTC偏移量:'-4:56:00'
== #XXX BROKEN, DO NOT DO IT
>>> dt = datetime(2014, 10, 6, tzinfo=pytz.timezone('US/Eastern'))
>>> dt
datetime.datetime(2014, 10, 6, 0, 0, tzinfo=<DstTzInfo 'US/Eastern' LMT-1 day, 19:04:00 STD>)
>>> dt.isoformat()
2014-10-06T00:00:00-04:56
。获得它的方法是使用不正确的代码:
tzinfo
直接分配pytz
不允许tzinfo
在给定时间内选择正确的tzinfo,而是使用可用的随机tz.localize()
对象。您应始终使用{{1}}附加正确的时区信息。
答案 2 :(得分:0)
我建议查看arrow。上述答案有效,但使代码真的令人困惑。 Arrow允许您使用以下方式执行此操作:
In [82]: start_time = arrow.get(2014, 10, 6, 18).to('US/Eastern')
In [83]: end_time = start_time.shift(seconds=400)
In [84]: start_time
Out[84]: <Arrow [2014-10-06T14:00:00-04:00]>
In [85]: end_time
Out[85]: <Arrow [2014-10-06T14:06:40-04:00]>
您可以使用
检索datetime
个对象
In [86]: start_time.datetime
Out[86]: datetime.datetime(2014, 10, 6, 14, 0, tzinfo=tzfile('/usr/share/zoneinfo/US/Eastern'))