Michelle Glauser
Michelle Glauser

Reputation: 1097

'datetime.datetime' object has no attribute 'read'

Users in my app have date_joined fields that are in this format: 2014-12-14 14:46:43.379518+00:00

In order to pass this datetime along to Intercom.io, it must be a UNIX timestamp like this: 1426020706 (this is not the same time, just an example).

I've tried several methods I've read here on Stack Overflow (nothing in this question has the same starting time format: Converting datetime.date to UTC timestamp in Python), but none have worked. mktime() seemed promising, but I got "'datetime.datetime' object has no attribute 'mktime'."

I just tried this:

import time
import dateutil.parser
import member.models import Member

member = Member.objects.get(email="[email protected]")
date_joined = member.date_joined
dt = dateutil.parser.parse(date_joined)
print int(time.mktime(dt.timetuple()))

It returned "'datetime.datetime' object has no attribute 'read'". How can I accomplish this?

Upvotes: 3

Views: 8933

Answers (5)

thekingoftruth
thekingoftruth

Reputation: 1781

I know this is an old post, but I want to highlight that the answer is likely what @Peter said in his comment:

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

So-- your model probably already parses into a datetime.datetime object for you.

Upvotes: 0

user3638751
user3638751

Reputation: 113

I had that problem when I used input from Django's DateField, which is displayed in a form of XXXX-YY-ZZ: parse(django_datefield) causes the exception.

The solution: use str(django_datefield).

parse(str(django_datefield))

Upvotes: 1

kenorb
kenorb

Reputation: 166765

You can try the following Python 3 code:

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()))

which prints:

1418568403.0

Upvotes: 2

jfs
jfs

Reputation: 414695

It seems you have an aware datetime object. If you print it then it looks like:

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

To be sure print(repr(date_joined)).

Converting datetime.date to UTC timestamp in Python shows several ways how you could get the timestamp e.g.,

timestamp = date_joined.timestamp() # in Python 3.3+

Or on older Python versions:

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()

Note: timestamp = calendar.timegm(date_joined.utctimetuple()) would also work in your case but it may return a wrong result silently if you pass it a naive datetime object that represents local time by mistake.

If your input is a time string then convert the time string into a datetime object first.

Upvotes: 4

jedwards
jedwards

Reputation: 30240

What about (using the dateutil and pytz packages):

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')

Which we can test with:

# 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

Output:

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

These output all the same timestamps, and "verification" formatted strings.

Upvotes: 3

Related Questions