将日期时间转换为 Unix 时间戳并将其转换回 python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19801727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert datetime to Unix timestamp and convert it back in python
提问by bridgewater
I have dt = datetime(2013,9,1,11)
, and I would like to get a Unix timestamp of this datetime object.
我有dt = datetime(2013,9,1,11)
,我想获得这个日期时间对象的 Unix 时间戳。
When I do (dt - datetime(1970,1,1)).total_seconds()
I got the timestamp 1378033200
.
当我这样做时,(dt - datetime(1970,1,1)).total_seconds()
我得到了时间戳1378033200
。
When converting it back using datetime.fromtimestamp
I got datetime.datetime(2013, 9, 1, 6, 0)
.
使用datetime.fromtimestamp
I got将其转换回时datetime.datetime(2013, 9, 1, 6, 0)
。
The hour doesn't match. What did I miss here?
小时不匹配。我在这里错过了什么?
采纳答案by abarnert
What you missed here is timezones.
你在这里错过的是时区。
Presumably you've five hours off UTC, so 2013-09-01T11:00:00 local and 2013-09-01T06:00:00Z are the same time.
大概你有五个小时的 UTC,所以 2013-09-01T11:00:00 本地和 2013-09-01T06:00:00Z 是同一时间。
You need to read the top of the datetime
docs, which explain about timezones and "naive" and "aware" objects.
您需要阅读datetime
文档的顶部,其中解释了时区以及“天真”和“感知”对象。
If your original naive datetime was UTC, the way to recover it is to use utcfromtimestamp
instead of fromtimestamp
.
如果你原来天真的日期时间为UTC,恢复它的方式是使用utcfromtimestamp
替代fromtimestamp
。
On the other hand, if your original naive datetime was local, you shouldn't have subtracted a UTC timestamp from it in the first place; use datetime.fromtimestamp(0)
instead.
另一方面,如果您最初的原始日期时间是本地的,您首先不应该从中减去 UTC 时间戳;使用datetime.fromtimestamp(0)
来代替。
Or, if you had an aware datetime object, you need to either use a local (aware) epoch on both sides, or explicitly convert to and from UTC.
或者,如果您有一个感知日期时间对象,则需要在双方使用本地(感知)纪元,或者显式转换为 UTC 或从 UTC 转换。
If you have, or can upgrade to, Python 3.3 or later, you can avoid all of these problems by just using the timestamp
method instead of trying to figure out how to do it yourself. And even if you don't, you may want to consider borrowing its source code.
如果您拥有或可以升级到 Python 3.3 或更高版本,则只需使用该timestamp
方法即可避免所有这些问题,而无需自己尝试弄清楚如何去做。即使您不这样做,您也可能需要考虑借用其源代码。
(And if you can wait for Python 3.4, it looks like PEP 341is likely to make it into the final release, which means all of the stuff J.F. Sebastian and I were talking about in the comments should be doable with just the stdlib, and working the same way on both Unix and Windows.)
(如果你可以等待 Python 3.4,看起来PEP 341很可能会进入最终版本,这意味着 JF Sebastian 和我在评论中谈论的所有内容都应该可以仅使用 stdlib,并且在 Unix 和 Windows 上以相同的方式工作。)
回答by Darren Stone
Rather than this expression to create a POSIX timestamp from dt
,
而不是这个表达式来创建一个 POSIX 时间戳dt
,
(dt - datetime(1970,1,1)).total_seconds()
Use this:
用这个:
int(dt.strftime("%s"))
I get the right answer in your example using the second method.
我在你的例子中使用第二种方法得到了正确的答案。
EDIT: Some followup... After some comments (see below), I was curious about the lack of support or documentation for %s
in strftime
. Here's what I found:
编辑:一些后续...在一些评论(见下文)之后,我很好奇缺乏支持或文档%s
in strftime
. 这是我发现的:
In the Python sourcefor datetime
and time
, the string STRFTIME_FORMAT_CODES
tells us:
在and的Python 源代码中,字符串告诉我们:datetime
time
STRFTIME_FORMAT_CODES
"Other codes may be available on your platform.
See documentation for the C library strftime function."
So now if we man strftime
(on BSD systems such as Mac OS X), you'll find support for %s
:
所以现在如果我们man strftime
(在 BSD 系统如 Mac OS X 上),你会发现支持%s
:
"%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))."
Anyways, that's why %s
works on the systems it does. But there are better solutions to OP's problem (that take timezones into account). See @abarnert's accepted answer here.
无论如何,这就是为什么%s
在它所做的系统上工作的原因。但是有更好的解决方案来解决 OP 的问题(考虑到时区)。请在此处查看@abernert 已接受的答案。
回答by Ronald Portier
Well, when converting TO unix timestamp, python is basically assuming UTC, but while converting back it will give you a date converted to your local timezone.
好吧,当转换为 unix 时间戳时,python 基本上假设 UTC,但在转换回来时,它会给你一个转换为本地时区的日期。
See this question/answer; Get timezone used by datetime.datetime.fromtimestamp()
看到这个问题/答案; 获取 datetime.datetime.fromtimestamp() 使用的时区
回答by DmitrySemenov
solution is
解决方案是
import time
import datetime
d = datetime.date(2015,1,5)
unixtime = time.mktime(d.timetuple())
回答by Francisco Costa
If you want to convert a python datetime to seconds since epoch you should do it explicitly:
如果要将 python 日期时间转换为自纪元以来的秒数,则应明确执行此操作:
>>> import datetime
>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'
>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0
In Python 3.3+ you can use timestamp()
instead:
在 Python 3.3+ 中,您可以timestamp()
改用:
>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
回答by maxkoryukov
You've missed the time zone info (already answered, agreed)
您错过了时区信息(已回答,已同意)
arrow
packageallows to avoid this torture with datetimes; It is already written, tested, pypi-published, cross-python (2.6 — 3.xx).
arrow
包允许避免这种日期时间的折磨;它已经编写、测试、pypi 发布、跨 python (2.6 — 3.xx)。
All you need: pip install arrow
(or add to dependencies)
您只需要:(pip install arrow
或添加到依赖项)
Solution for your case
您的情况的解决方案
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'
回答by Matt Kramer
If your datetime object represents UTC time, don't use time.mktime, as it assumes the tuple is in your local timezone. Instead, use calendar.timegm:
如果您的 datetime 对象表示 UTC 时间,请不要使用 time.mktime,因为它假定元组位于您的本地时区。相反,使用 calendar.timegm:
>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60
回答by wyx
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)
If you want UTC timestamp :time.mktime
just for localdt .Use calendar.timegm
is safe but dt must the utc zone so change the zone to utc. If dt in UTC just use calendar.timegm
.
如果您想要 UTC 时间戳:time.mktime
仅用于本地dt 。使用calendar.timegm
是安全的,但 dt 必须是 utc 区域,因此将区域更改为 utc。如果 dt 在 UTC 中,只需使用calendar.timegm
.
回答by Emin Temiz
For working with UTC timezones:
使用 UTC 时区:
time_stamp = calendar.timegm(dt.timetuple())
datetime.utcfromtimestamp(time_stamp)
回答by rjha94
def datetime_to_epoch(d1):
# create 1,1,1970 in same timezone as d1
d2 = datetime(1970, 1, 1, tzinfo=d1.tzinfo)
time_delta = d1 - d2
ts = int(time_delta.total_seconds())
return ts
def epoch_to_datetime_string(ts, tz_name="UTC"):
x_timezone = timezone(tz_name)
d1 = datetime.fromtimestamp(ts, x_timezone)
x = d1.strftime("%d %B %Y %H:%M:%S")
return x