我有dt = datetime(2013,9,1,11),我想获得这个datetime对象的Unix时间戳。
当我做(dt - datetime(1970,1,1)).total_seconds()时,我得到了时间戳1378033200。
当转换回使用datetime.fromtimestamp时,我得到了datetime。Datetime(2013, 9,1,6,0)。
时间不对。我错过了什么?
我有dt = datetime(2013,9,1,11),我想获得这个datetime对象的Unix时间戳。
当我做(dt - datetime(1970,1,1)).total_seconds()时,我得到了时间戳1378033200。
当转换回使用datetime.fromtimestamp时,我得到了datetime。Datetime(2013, 9,1,6,0)。
时间不对。我错过了什么?
当前回答
您错过了时区信息(已回答,同意)
箭包允许避免这种折磨与日期时间;它已经被编写、测试、pypi发布、跨python (2.6 - 3.xx)。
所有你需要的:pip安装箭头(或添加到依赖项)
解决你的问题
dt = datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200
bc = arrow.get(1378033200).datetime
print(bc)
# >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
print(bc.isoformat())
# >>> '2013-09-01T11:00:00+00:00'
其他回答
你错过的是时区。
假设你距离UTC时间还有5个小时,所以2013-09-01T11:00:00 local时间和2013-09-01T06:00:00Z时间是相同的。
你需要阅读datetime文档的顶部,它解释了时区和“naive”和“aware”对象。
如果您最初的天真datetime是UTC,那么恢复它的方法是使用utcfromtimestamp而不是fromtimestamp。
另一方面,如果您最初的天真datetime是本地的,那么首先就不应该从中减去UTC时间戳;使用datetime.fromtimestamp(0)代替。
或者,如果您有一个可感知的datetime对象,则需要在两侧使用一个本地(可感知的)epoch,或者显式地与UTC进行转换。
如果你已经或可以升级到Python 3.3或更高版本,你可以通过使用时间戳方法来避免所有这些问题,而不是试图自己弄清楚如何做。即使你不知道,你也可以考虑借用它的源代码。
(如果你能等到Python 3.4, PEP 341看起来很可能会进入最终版本,这意味着J.F. Sebastian和我在评论中谈论的所有东西都可以用stdlib完成,并且在Unix和Windows上都可以以相同的方式工作。)
与其用这个表达式从dt中创建POSIX时间戳,
(dt - datetime(1970,1,1)).total_seconds()
用这个:
int(dt.strftime("%s"))
我用第二种方法在你的例子中得到了正确答案。
编辑:一些后续…经过一些评论(见下文)后,我对strftime中缺少对%s的支持或文档感到好奇。以下是我的发现:
在datetime和time的Python源代码中,字符串STRFTIME_FORMAT_CODES告诉我们:
"Other codes may be available on your platform.
See documentation for the C library strftime function."
所以现在如果我们使用strftime(在Mac OS X等BSD系统上),你会发现对%s的支持:
"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."
不管怎样,这就是为什么%s在系统中起作用。但是对于OP的问题,有更好的解决方案(将时区考虑在内)。请看@abarnert的接受答案。
def dt2ts(dt, utc=False):
if utc:
return calendar.timegm(dt.timetuple())
if dt.tzinfo is None:
return int(time.mktime(dt.timetuple()))
utc_dt = dt.astimezone(tz.tzutc()).timetuple()
return calendar.timegm(utc_dt)
如果你想要UTC时间戳:时间。mktime仅用于本地dt。使用日历。Timegm是安全的,但dt必须在utc区域,所以将区域更改为utc。如果dt是UTC,则使用calendar.timegm。
当转换为unix时间戳时,python基本上是假设UTC,但在转换回来时,它会给你一个转换为本地时区的日期。
请看这个问题/答案; 获取datetime.datetime.fromtimestamp()使用的时区
您错过了时区信息(已回答,同意)
箭包允许避免这种折磨与日期时间;它已经被编写、测试、pypi发布、跨python (2.6 - 3.xx)。
所有你需要的:pip安装箭头(或添加到依赖项)
解决你的问题
dt = datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200
bc = arrow.get(1378033200).datetime
print(bc)
# >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
print(bc.isoformat())
# >>> '2013-09-01T11:00:00+00:00'