Reputation: 1097
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
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
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
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
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
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