我使用feedparser从一些RSS提要中获取条目。 这些条目有一个published_parsed字段,由feedparser解析为time.structtime。
我使用此函数将time.structtime转换为datetime.datetime:
def publishParsedToDatetime(structTime):
return datetime.datetime.fromtimestamp(time.mktime(structTime))
输入(structtime):
time.struct_time(tm_year=2015, tm_mon=8, tm_mday=1, tm_hour=20, tm_min=28, tm_sec=33, tm_wday=5, tm_yday=213, tm_isdst=0)
输出(日期时间):
2015-08-01 21:28:33
我发现可能与时区相关的问题,structtime和datetime值之间存在 1小时差异。
structtime值为UTC。 但是datetime.datetime值既不是UTC,也不是我当前的时区(CET,中欧时间,我们观察夏令时,所以我们现在有UTC + 2小时)。
如何解释?
答案 0 :(得分:1)
实际上,正如documentation for datetime.fromtimestamp
中所述,它默认转换为本地时间:
返回与POSIX时间戳对应的本地日期和时间,例如time.time()返回的日期和时间。如果可选参数tz为None或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime对象是天真的
然后field tm_isdst=0
告诉它不使用夏令时(尽管当地时区使用它),可以解释1小时的差异。
为了更清楚地看到这一点,我们构建了两个测试用例
glob.glob
输出如下:
import time, datetime
# this is how your time object was constructed before
tm_isdst = 0
t = time.mktime((2015, 8, 1, 20, 28, 33, 5, 213, tm_isdst))
print("Old conversion: {0}".format(datetime.datetime.fromtimestamp(t)))
# this is what happens if you let mktime "divine" a time zone
tm_isdst = -1
t = time.mktime((2015, 8, 1, 20, 28, 33, 5, 213, tm_isdst))
print("New conversion: {0}".format(datetime.datetime.fromtimestamp(t)))
然后,问题是,传递给Old conversion: 2015-08-01 21:28:33
New conversion: 2015-08-01 20:28:33
的{{1}}对象有structTime
,但您要解析的时间戳是DST时区。
正如您在另一条评论中已经注意到的,对此的正确解决方案可能是始终在后端代码中使用UTC,并且仅在向用户显示时间或读取用户输入时执行时区处理。
答案 1 :(得分:1)
calendar.timegm
将 UTC timetuple作为输入并返回其时间戳。
相反,time.mktime
将 local timetuple作为输入并返回其(UTC)时间戳。所有时间戳代表自纪元,1970-1-1 00:00:00 UTC以来的秒数。
utcfromtimestamp
将时间戳作为输入并将其转换为天真的
(即时区不知道)UTC日期时间。
fromtimestamp
采用相同的时间戳并将其转换为相应的时间戳
天真的当地日期时间。
由于您的时间段(例如structTime
)是UTC时间段,因此您应使用calendar.timegm
而不是time.mktime
来查找正确的时间戳。
获得正确的时间戳后,fromtimestamp
将返回相应的天真本地日期时间。
import time
import calendar
import datetime as DT
timetuple = (2015, 8, 1, 20, 28, 33, 5, 213, 0)
timestamp = calendar.timegm(timetuple)
naive_local_date = DT.datetime.fromtimestamp(timestamp)
print('Naive local: {}'.format(naive_local_date))
产量
Naive local: 2015-08-01 22:28:33