![](/img/trans.png)
[英]In Python, how do you convert seconds since epoch to a `datetime` object?
[英]In Python, how do you convert a `datetime` object to seconds?
我有一堆日期时间对象,我想为每个对象计算自过去固定时间以来的秒数(例如自 1970 年 1 月 1 日起)。
import datetime
t = datetime.datetime(2009, 10, 21, 0, 0)
这似乎只是区分具有不同日期的日期:
t.toordinal()
如何将datetime
时间 object 转换为秒数?
对于 1970 年 1 月 1 日这一特殊日期,有多种选择。
对于任何其他开始日期,您需要以秒为单位获得两个日期之间的差异。 减去两个日期给出一个timedelta
对象,从 Python 2.7 开始,它有一个total_seconds()
函数。
>>> (t-datetime.datetime(1970,1,1)).total_seconds()
1256083200.0
开始日期通常以 UTC 指定,因此为了获得正确的结果,您输入此公式的datetime
也应使用 UTC。 如果您的datetime
时间不是 UTC,则您需要在使用它之前对其进行转换,或者附加一个具有适当偏移量的tzinfo
类。
如评论中所述,如果您的datetime
附加了tzinfo
,那么您在开始日期也需要一个tzinfo
,否则减法将失败; 对于上面的示例,如果使用 Python 2,我会添加tzinfo=pytz.utc
如果使用 Python 3,我会添加tzinfo=timezone.utc
。
从 Python 3.3 开始,这使用datetime.timestamp()
方法变得非常容易。 这当然只有在您需要 1970-01-01 UTC 的秒数时才有用。
from datetime import datetime
dt = datetime.today() # Get timezone naive now
seconds = dt.timestamp()
返回值将是一个表示偶数几分之一秒的浮点数。 如果 datetime 是 timezone naive(如上例所示),则假定 datetime 对象表示本地时间,即它是从您所在位置的当前时间到 1970-01-01 UTC 的秒数。
要获取 Unix 时间(自 1970 年 1 月 1 日以来的秒数):
>>> import datetime, time
>>> t = datetime.datetime(2011, 10, 21, 0, 0)
>>> time.mktime(t.timetuple())
1319148000.0
也许题外话:从日期时间获取 UNIX/POSIX 时间并将其转换回来:
>>> import datetime, time
>>> dt = datetime.datetime(2011, 10, 21, 0, 0)
>>> s = time.mktime(dt.timetuple())
>>> s
1319148000.0
# and back
>>> datetime.datetime.fromtimestamp(s)
datetime.datetime(2011, 10, 21, 0, 0)
请注意,不同的时区对结果有影响,例如我当前的 TZ/DST 回报:
>>> time.mktime(datetime.datetime(1970, 1, 1, 0, 0).timetuple())
-3600 # -1h
因此,应该考虑通过使用函数的 UTC 版本来标准化为 UTC。
请注意,先前的结果可用于计算当前时区的 UTC 偏移量。 在本例中,这是 +1h,即 UTC+0100。
参考:
int (t.strftime("%s"))
也有效
来自 python 文档:
timedelta.total_seconds()
返回持续时间中包含的总秒数。 相当于
(td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
在启用真除法的情况下计算。
请注意,对于非常大的时间间隔(在大多数平台上超过 270 年),此方法将失去微秒精度。
此功能是 2.7 版中的新增功能。
比较 4 种最常见的方法,以确保准确性:
方式一:人工计算
from datetime import datetime
total1 = int(datetimeobj.strftime('%S'))
total1 += int(datetimeobj.strftime('%M')) * 60
total1 += int(datetimeobj.strftime('%H')) * 60 * 60
total1 += (int(datetimeobj.strftime('%j')) - 1) * 60 * 60 * 24
total1 += (int(datetimeobj.strftime('%Y')) - 1970) * 60 * 60 * 24 * 365
print ("Method #1: Manual")
print ("Before: %s" % datetimeobj)
print ("Seconds: %s " % total1)
print ("After: %s" % datetime.fromtimestamp(total1))
Output:
Method #1: Manual
Before: 1970-10-01 12:00:00
Seconds: 23630400
After: 1970-10-01 16:00:00
精度测试:FAIL(时区偏移)
方法二:时间模块
import time
from datetime import datetime
total2 = int(time.mktime(datetimeobj.timetuple()))
print ("Method #2: Time Module")
print ("Before: %s" % datetimeobj)
print ("Seconds: %s " % total2)
print ("After: %s" % datetime.fromtimestamp(total2))
Output:
Method #2: Time Module
Before: 1970-10-01 12:00:00
Seconds: 23616000
After: 1970-10-01 12:00:00
精度测试:通过
方法三:日历模块
import calendar
from datetime import datetime
total3 = calendar.timegm(datetimeobj.timetuple())
print ("Method #3: Calendar Module")
print ("Before: %s" % datetimeobj)
print ("Seconds: %s " % total3)
print ("After: %s" % datetime.fromtimestamp(total3))
Output:
Method #3: Calendar Module
Before: 1970-10-01 12:00:00
Seconds: 23616000
After: 1970-10-01 16:00:00
精度测试:FAIL(时区偏移)
方法四:Datetime 时间戳
from datetime import datetime
total4 = datetimeobj.timestamp()
print ("Method #4: datetime timestamp")
print ("Before: %s" % datetimeobj)
print ("Seconds: %s " % total4)
print ("After: %s" % datetime.fromtimestamp(total4))
Output:
Method #2: Time Module
Before: 1970-10-01 12:00:00
Seconds: 23616000
After: 1970-10-01 12:00:00
精度测试:通过
结论
我没有在所有答案中看到这一点,尽管我猜这是默认需要:
t_start = datetime.now()
sleep(2)
t_end = datetime.now()
duration = t_end - t_start
print(round(duration.total_seconds()))
如果您不使用.total_seconds()
,它会抛出: TypeError: type datetime.timedelta doesn't define __round__ method
。
例子:
>>> duration
datetime.timedelta(seconds=53, microseconds=621861)
>>> round(duration.total_seconds())
54
>>> duration.seconds
53
获取duration.seconds
只需要秒,不考虑微秒,就像你运行math.floor(duration.total_seconds())
一样。
要将表示 UTC 时间的 datetime 对象转换为 POSIX 时间戳:
from datetime import timezone
seconds_since_epoch = utc_time.replace(tzinfo=timezone.utc).timestamp()
要将表示本地时区时间的 datetime 对象转换为 POSIX 时间戳:
import tzlocal # $ pip install tzlocal
local_timezone = tzlocal.get_localzone()
seconds_since_epoch = local_timezone.localize(local_time, is_dst=None).timestamp()
请参阅如何在 Python 中将本地时间转换为 UTC? 如果 tz 数据库在给定平台上可用; 仅标准库的解决方案可能有效。
如果您需要<3.3
Python 版本的解决方案,请点击链接。
我尝试了标准库的calendar.timegm并且效果很好:
# convert a datetime to milliseconds since Epoch
def datetime_to_utc_milliseconds(aDateTime):
return int(calendar.timegm(aDateTime.timetuple())*1000)
参考:https ://docs.python.org/2/library/calendar.html#calendar.timegm
Python 提供了对日期时间的操作来计算两个日期之间的差异。 在你的情况下,这将是:
t - datetime.datetime(1970,1,1)
返回的值是一个 timedelta 对象,您可以使用成员函数total_seconds从中获取以秒为单位的值。
(t - datetime.datetime(1970,1,1)).total_seconds()
import datetime
import math
def getSeconds(inputDate):
time = datetime.date.today().strftime('%m/%d/%Y')
date_time = datetime.datetime.strptime(time, '%m/%d/%Y')
msg = inputDate
props = msg.split(".")
a_timedelta = datetime.timedelta
if(len(props)==3):
a_timedelta = date_time - datetime.datetime(int(props[0]),int(props[1]),int(props[2]))
else:
print("Invalid date format")
return
seconds = math.trunc(a_timedelta.total_seconds())
print(seconds)
return seconds
示例 getSeconds("2022.1.1")
在 python 3.x 中以毫秒为单位查找代码块处理时间的标准方法如下:
import datetime
t_start = datetime.datetime.now()
# Here is the python3 code, you want
# to check the processing time of
t_end = datetime.datetime.now()
print("Time taken : ", (t_end - t_start).total_seconds()*1000, " ms")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.