[英]Converting datetime.date to UTC timestamp in Python
I am dealing with dates in Python and I need to convert them to UTC timestamps to be used inside Javascript.我正在处理 Python 中的日期,我需要将它们转换为 UTC 时间戳以在 Javascript 中使用。 The following code does not work:
以下代码不起作用:
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
Converting the date object first to datetime also does not help.首先将日期对象转换为日期时间也无济于事。 I tried the example at this link from, but:
我在此链接中尝试了示例,但是:
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
and now either:现在要么:
mktime(utc.localize(input_date).utctimetuple())
or要么
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
does work.确实有效。
So general question: how can I get a date converted to seconds since epoch according to UTC?那么普遍的问题:如何根据UTC将日期转换为自纪元以来的秒数?
If d = date(2011, 1, 1)
is in UTC:如果
d = date(2011, 1, 1)
是 UTC:
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
If d
is in local timezone:如果
d
在本地时区:
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
timestamp1
and timestamp2
may differ if midnight in the local timezone is not the same time instance as midnight in UTC.如果本地时区的午夜与 UTC 的午夜不是同一时间实例,则
timestamp1
和timestamp2
可能不同。
mktime()
may return a wrong result if d
corresponds to an ambiguous local time (eg, during DST transition) or if d
is a past(future) date when the utc offset might have been different and the C mktime()
has no access to the tz database on the given platform.如果
d
对应于不明确的本地时间(例如,在 DST 转换期间),或者如果d
是过去(未来)日期,此时 utc 偏移量可能不同并且C mktime()
无法访问,则mktime()
可能返回错误结果到给定平台上的 tz 数据库。 You could use pytz
module (eg, via tzlocal.get_localzone()
) to get access to the tz database on all platforms .您可以使用
pytz
模块(例如,通过tzlocal.get_localzone()
)来访问所有平台上的 tz 数据库。 Also, utcfromtimestamp()
may fail and mktime()
may return non-POSIX timestamp if "right"
timezone is used .此外, 如果使用
"right"
时区,则utcfromtimestamp()
可能会失败并且mktime()
可能会返回非 POSIX 时间戳。
To convert datetime.date
object that represents date in UTC without calendar.timegm()
:要在不使用
calendar.timegm()
情况下转换表示 UTC 日期的datetime.date
对象:
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
To convert datetime.datetime
(not datetime.date
) object that already represents time in UTC to the corresponding POSIX timestamp (a float
).将已经表示 UTC 时间的
datetime.datetime
(不是datetime.date
)对象转换为相应的 POSIX 时间戳(一个float
)。
datetime.timestamp()
: datetime.timestamp()
:
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Note: It is necessary to supply timezone.utc
explicitly otherwise .timestamp()
assume that your naive datetime object is in local timezone.注意:有必要明确提供
timezone.utc
否则.timestamp()
假设您的原始日期时间对象位于本地时区。
From the docs for datetime.utcfromtimestamp()
:来自
datetime.utcfromtimestamp()
的文档:
There is no method to obtain the timestamp from a datetime instance, but POSIX timestamp corresponding to a datetime instance dt can be easily calculated as follows.
没有方法可以从日期时间实例中获取时间戳,但是可以很容易地计算出日期时间实例 dt 对应的 POSIX 时间戳,如下所示。 For a naive dt:
对于一个天真的 dt:
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
And for an aware dt:
对于一个有意识的 dt:
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
Interesting read: Epoch time vs. time of day on the difference between What time is it?有趣的阅读:纪元时间与一天中的时间之间的区别是什么时间? and How many seconds have elapsed?
和已经过去了多少秒?
See also: datetime needs an "epoch" method另见:日期时间需要一个“纪元”方法
To adapt the above code for Python 2:为 Python 2 调整上述代码:
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
where timedelta.total_seconds()
is equivalent to (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
computed with true division enabled.其中
timedelta.total_seconds()
相当于(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
在启用真正除法的情况下计算。
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, epoch=datetime(1970,1,1)):
td = dt - epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
Beware of floating-point issues .注意浮点问题。
2012-01-08 15:34:10.022403
1326036850.02
datetime
object to POSIX timestampdatetime
对象转换为 POSIX 时间戳assert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
On Python 3:在 Python 3 上:
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)
On Python 2:在 Python 2 上:
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
For unix systems only :仅适用于unix 系统:
>>> import datetime
>>> d = datetime.date(2011, 1, 1)
>>> d.strftime("%s") # <-- THIS IS THE CODE YOU WANT
'1293832800'
Note 1: dizzyf observed that this applies localized timezones .注 1: dizzyf 观察到这适用于本地化时区。 Don't use in production.
不要在生产中使用。
Note 2: Jakub Narębski noted that this ignores timezone information even for offset-aware datetime (tested for Python 2.7).注 2: Jakub Narębski 指出,即使对于偏移感知日期时间(针对 Python 2.7 进行测试),这也会忽略时区信息。
Assumption 1: You're attempting to convert a date to a timestamp, however since a date covers a 24 hour period, there isn't a single timestamp that represents that date.假设 1:您正在尝试将日期转换为时间戳,但是由于日期涵盖 24 小时,因此没有代表该日期的单个时间戳。 I'll assume that you want to represent the timestamp of that date at midnight (00:00:00.000).
我假设您想在午夜 (00:00:00.000) 表示该日期的时间戳。
Assumption 2: The date you present is not associated with a particular time zone, however you want to determine the offset from a particular time zone (UTC).假设 2:您显示的日期与特定时区无关,但是您想要确定与特定时区 (UTC) 的偏移量。 Without knowing the time zone the date is in, it isn't possible to calculate a timestamp for a specific time zone.
如果不知道日期所在的时区,则无法计算特定时区的时间戳。 I'll assume that you want to treat the date as if it is in the local system time zone.
我假设您希望将日期视为在本地系统时区中。
First, you can convert the date instance into a tuple representing the various time components using the timetuple()
member:首先,您可以使用
timetuple()
成员将日期实例转换为表示各种时间组件的元组:
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
You can then convert that into a timestamp using time.mktime
:然后,您可以使用
time.mktime
将其转换为时间戳:
ts = time.mktime(dtt) # 1293868800.0
You can verify this method by testing it with the epoch time itself (1970-01-01), in which case the function should return the timezone offset for the local time zone on that date:您可以通过使用纪元时间本身 (1970-01-01) 对其进行测试来验证此方法,在这种情况下,该函数应返回该日期本地时区的时区偏移量:
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0
is 8 hours, which would be correct for the Pacific time zone (where I'm at). 28800.0
是 8 小时,这对于太平洋时区(我所在的地方)来说是正确的。
I defined my own two functions我定义了自己的两个函数
here:这里:
import time
import datetime
from pytz import timezone
import calendar
import pytz
def utc_time2datetime(utc_time, tz=None):
# convert utc time to utc datetime
utc_datetime = datetime.datetime.fromtimestamp(utc_time)
# add time zone to utc datetime
if tz is None:
tz_datetime = utc_datetime.astimezone(timezone('utc'))
else:
tz_datetime = utc_datetime.astimezone(tz)
return tz_datetime
def datetime2utc_time(datetime):
# add utc time zone if no time zone is set
if datetime.tzinfo is None:
datetime = datetime.replace(tzinfo=timezone('utc'))
# convert to utc time zone from whatever time zone the datetime is set to
utc_datetime = datetime.astimezone(timezone('utc')).replace(tzinfo=None)
# create a time tuple from datetime
utc_timetuple = utc_datetime.timetuple()
# create a time element from the tuple an add microseconds
utc_time = calendar.timegm(utc_timetuple) + datetime.microsecond / 1E6
return utc_time
follow the python2.7 document, you have to use calendar.timegm() instead of time.mktime()按照python2.7文档,你必须使用 calendar.timegm() 而不是 time.mktime()
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(calendar.timegm(d.timetuple()))
datetime.datetime(2011, 1, 1, 0, 0)
i'm impressed of the deep discussion.我对深入的讨论印象深刻。
my 2 cents:我的 2 美分:
from datetime import datetime import time从日期时间导入日期时间导入时间
the timestamp in utc is: UTC 中的时间戳是:
timestamp = \
(datetime.utcnow() - datetime(1970,1,1)).total_seconds()
or,要么,
timestamp = time.time()
if now results from datetime.now(), in the same DST如果现在来自 datetime.now(),在同一个 DST 中
utcoffset = (datetime.now() - datetime.utcnow()).total_seconds()
timestamp = \
(now - datetime(1970,1,1)).total_seconds() - utcoffset
A complete time-string contains:一个完整的时间字符串包含:
[+HHMM or -HHMM]
[+HHMM or -HHMM]
For example:例如:
1970-01-01 06:00:00 +0500
== 1970-01-01 01:00:00 +0000
== UNIX timestamp:3600
1970-01-01 06:00:00 +0500
== 1970-01-01 01:00:00 +0000
1970-01-01 06:00:00 +0500
1970-01-01 01:00:00 +0000
== UNIX timestamp:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
Note:笔记:
UNIX timestamp
is a floating point number expressed in seconds since the epoch, in UTC .UNIX timestamp
是一个浮点数,以自纪元以来的秒数表示,以UTC 为单位。
Edit:编辑:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600
the question is a little confused.这个问题有点困惑。 timestamps are not UTC - they're a Unix thing.
时间戳不是 UTC - 它们是 Unix 的东西。 the date might be UTC?
日期可能是UTC? assuming it is, and if you're using Python 3.2+, simple-date makes this trivial:
假设是这样,并且如果您使用的是 Python 3.2+,则simple-date会使这变得微不足道:
>>> SimpleDate(date(2011,1,1), tz='utc').timestamp
1293840000.0
if you actually have the year, month and day you don't need to create the date
:如果您确实有年、月和日,则不需要创建
date
:
>>> SimpleDate(2011,1,1, tz='utc').timestamp
1293840000.0
and if the date is in some other timezone (this matters because we're assuming midnight without an associated time):如果日期在其他时区(这很重要,因为我们假设没有相关时间的午夜):
>>> SimpleDate(date(2011,1,1), tz='America/New_York').timestamp
1293858000.0
[the idea behind simple-date is to collect all python's date and time stuff in one consistent class, so you can do any conversion. [ simple-date 背后的想法是在一个一致的类中收集所有 python 的日期和时间内容,因此您可以进行任何转换。 so, for example, it will also go the other way:
所以,例如,它也会走另一条路:
>>> SimpleDate(1293858000, tz='utc').date
datetime.date(2011, 1, 1)
] ]
Considering you have a datetime
object called d
, use the following to get the timestamp in UTC:考虑到您有一个名为
d
的datetime
对象,请使用以下内容获取 UTC 中的时间戳:
d.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
And for the opposite direction, use following :对于相反的方向,请使用以下内容:
d = datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
This works for me, pass through a function.这对我有用,通过一个函数。
from datetime import timezone, datetime, timedelta
import datetime
def utc_converter(dt):
dt = datetime.datetime.now(timezone.utc)
utc_time = dt.replace(tzinfo=timezone.utc)
utc_timestamp = utc_time.timestamp()
return utc_timestamp
# create start and end timestamps
_now = datetime.datetime.now()
str_start = str(utc_converter(_now))
_end = _now + timedelta(seconds=10)
str_end = str(utc_converter(_end))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.