我有一个应该在EST的时间戳:
2014-10-06T18:06:40-04:56
Run Code Online (Sandbox Code Playgroud)
我理解这第一部分: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)
Run Code Online (Sandbox Code Playgroud)
然后:
end_time.isoformat()
Run Code Online (Sandbox Code Playgroud)
收益:
2014-10-06T18:06:40-04:56
Run Code Online (Sandbox Code Playgroud)
aba*_*ert 23
问题是pytz:
...与用于tzinfo实现的文档化Python API不同; 如果要创建本地wallclock时间,则需要使用本
localize()文档中记录的方法...
再往下说,它说:
不幸的是,对于许多时区,使用标准日期时间构造函数的tzinfo参数"不起作用".
>>> datetime(2002, 10, 27, 12, 0, 0, tzinfo=amsterdam).strftime(fmt)
'2002-10-27 12:00:00 LMT+0020'
Run Code Online (Sandbox Code Playgroud)
因此,您需要执行文档建议使用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'
Run Code Online (Sandbox Code Playgroud)
我想这是你想要的最后一次.作为文件localize说:
将天真时间转换为当地时间.
此方法应该用于构造localtimes,而不是将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,夏季是美国东部时间,冬季是美国东部时间,这是你从仰视'US/Eastern'或'America/New_York'.
-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())
Run Code Online (Sandbox Code Playgroud)
tz.localize()而不是tzinfo直接分配属性is_dst=None 断言输入时间存在且无歧义tz.normalize() 如果日期算术跨越DST边界,则很有必要2014-10-06T18:06:40-04:00
2014-10-06T18:13:20-04:00
Run Code Online (Sandbox Code Playgroud)
为什么你需要localize(),normalize()在描述的pytz文档(对部分localize()/ normalize()是文档中的第一个音符)。
-04:56UTC偏移量是错误的2014由于DST转换或其他原因(例如战争或某些政治家认为这是个好主意),同一时间的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>}
Run Code Online (Sandbox Code Playgroud)
注意LMT tzinfo的UTC偏移量:timedelta(-1, 68640)== '-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
Run Code Online (Sandbox Code Playgroud)
tzinfo直接分配不允许pytz在给定的时间内选择正确的tzinfo,tzinfo而是使用可用的随机对象代替。您应该始终使用tz.localize()附加正确的时区信息。
| 归档时间: |
|
| 查看次数: |
3317 次 |
| 最近记录: |