“datetime.datetime”对象没有“read”属性。

3
在我的应用程序中,用户的date_joined字段格式如下:2014-12-14 14:46:43.379518+00:00
为了将此日期时间传递给Intercom.io,它必须是UNIX时间戳,如1426020706(这不是同一时间,只是一个示例)。
我尝试了在Stack Overflow上阅读到的几种方法(此问题中没有相同的起始时间格式:在Python中将datetime.date转换为UTC时间戳),但是都没有成功。mktime()似乎很有前途,但我得到了“'datetime.datetime' object has no attribute 'mktime'.”。
我刚刚尝试了这个:
import time
import dateutil.parser
import member.models import Member

member = Member.objects.get(email="aspeksnijder@outlook.com")
date_joined = member.date_joined
dt = dateutil.parser.parse(date_joined)
print int(time.mktime(dt.timetuple()))

它返回了“'datetime.datetime'对象没有属性'read'”。我该怎么做?

https://dev59.com/XkjSa4cB1Zd3GeqPJez_ - heinst
1
看起来 member.date_joined 已经是一个日期时间对象了,不需要解析它。 - Peter
5个回答

4

看起来您有一个意识到的日期时间对象。如果您打印它,它会显示为:

2014-12-14 14:46:43.379518+00:00

确保 print(repr(date_joined))将 datetime.date 转换为 Python 中的 UTC 时间戳 展示了你可以获取时间戳的多种方式,例如,
timestamp = date_joined.timestamp() # in Python 3.3+

或在较旧版本的Python中:

from datetime import datetime

# local time = utc time + utc offset
utc_naive = date_joined.replace(tzinfo=None) - date_joined.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()

注意:timestamp = calendar.timegm(date_joined.utctimetuple()) 在您的情况下也可以使用,但如果您错误地传递了表示本地时间的naive datetime对象,则可能会静默地返回错误结果。
如果您的输入是一个时间字符串,那么请先将其转换为datetime对象。 (参考链接)

3

使用 dateutilpytz 包呢?

import dateutil.parser
from datetime import datetime
import calendar
import pytz

def str2ts(s):
    ''' Turns a string into a non-naive datetime object, then get the timestamp '''
    # However you get from your string to datetime.datetime object
    dt = dateutil.parser.parse(s)           # String to non-naive datetime
    dt = pytz.utc.normalize(dt)             # Normalize datetime to UTC
    ts = calendar.timegm(dt.timetuple())    # Convert UTC datetime to UTC timestamp
    return int(ts)

def ts2str(ts):
    '''Convert a UTC timestamp into a UTC datetime, then format it to a string'''
    dt = datetime.utcfromtimestamp(ts)      # Convert a UTC timestamp to a naive datetime object
    dt = dt.replace(tzinfo=pytz.utc)        # Convert naive datetime to non-naive
    return dt.strftime('%Y-%m-%d %H:%M:%S.%f%z')

我们可以用以下方式进行测试:
# A list of strings corresponding to the same time, with different timezone offsets
ss = [
    '2014-12-14 14:46:43.379518+00:00',
    '2014-12-14 15:46:43.379518+01:00',
    '2014-12-14 16:46:43.379518+02:00',
    '2014-12-14 17:46:43.379518+03:00',
]    

for s in ss:
    ts = str2ts(s)
    s2 = ts2str(ts)

    print ts, s2

输出:

1418568403 2014年12月14日 14:46:43.000000+0000
1418568403 2014年12月14日 14:46:43.000000+0000
1418568403 2014年12月14日 14:46:43.000000+0000
1418568403 2014年12月14日 14:46:43.000000+0000

这些输出都是相同的时间戳和“验证”格式化字符串。


我尝试了一下,得到了这个错误信息:"AttributeError: 'datetime.datetime'对象没有'read'属性"。 - Michelle Glauser
1
看起来执行 "date_joined = str(member.date_joined)" 工作了。 - Michelle Glauser
@jedwards 解析函数无法处理时区。 - heinst
@heinst dateutil.parser.parse 处理时区问题很好(参见:print(repr(dateutil.parser.parse(<带有时区的字符串>))))。然而,我假设所有的字符串都是在UTC时间下的,现在我会更新我的回答,提供更加健壮的解决方案。 - jedwards
更新了代码,可以正确处理具有不同时区偏移量的字符串。 - jedwards
@MichelleGlauser:如果您想获取时间戳,请不要将date_joined转换为字符串。错误消息显示您已经拥有了datetime对象。在这里不需要使用dateutil.parser.parse - jfs

2

您可以尝试以下 Python 3 代码:

import time, datetime
print(time.mktime(datetime.datetime.strptime("2014-12-14 14:46:43.379518", '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc).timetuple()))

它会打印出:

1418568403.0

downvote: mktime() 除非本地时区是 UTC(注意:问题中的 +00:00),否则就是错误的。 - jfs

1
当我使用Django的元素时,遇到了这个问题,它以“XXXX-YY-ZZ”的形式显示:parse(django_datefield)会导致异常。

解决方案:使用str(django_datefield)
parse(str(django_datefield))

1
踩票。为什么要将 datetime 对象转换为字符串,然后再解析回来呢? - jfs

0

我知道这是一个旧帖子,但我想强调答案很可能就是@Peter在他的评论中提到的:

It looks like member.date_joined is already a datetime object, and there's no need to parse it. – Peter Feb 25 '17 at 0:33

所以,你的模型可能已经为你解析成了datetime.datetime对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接