Converting to unix timestamp Python - python

I am trying to convert a datestamp of now into Unix TimeStamp, however the code below seems to be hit but then just jumps to the end of my app, as in seems to not like the time.mktime part.
from datetime import datetime
import time
now = datetime.now()
toDayDate = now.replace(hour=0, minute=0, second=0, microsecond=0)
newDate = time.mktime(datetime.strptime(toDayDate, "%Y-%m-%d %H:%M:%S").timetuple())
print(newDate)

Change
newDate = time.mktime(datetime.strptime(toDayDate, "%Y-%m-%d %H:%M:%S").timetuple())
to
newDate = time.mktime(datetime.timetuple())
as an example I did:
from datetime import datetime
from time import mktime
t = datetime.now()
unix_secs = mktime(t.timetuple())
and got unix_secs = 1488214742.0
Credit to #tarashypka- use t.utctimetuple() if you want the result in UTC (e.g. if your datetime object is aware of timezones)

You could use datetime.timestamp() in Python 3 to get the POSIX timestamp instead of using now().
The value returned is of type float. timestamp() relies on datetime which in turn relies on mktime(). However, datetime.timestamp() supports more platforms and has a wider range of values.

Related

How to format a date value for Hubspot API using Python

I have read the docs saying that to pass the value for a Hubspot date field you should format your Date as midnight UTC. However, I've had no luck doing so in Python. I assume I am just missing the magic Python incantation that will get the right result. Here is what I have:
from pytz import timezone, utc
from hubspot.crm.contacts import SimplePublicObject,
created_dt = # datetime from sqlalchemy query
utcdt = utc.localize(
datetime(
year=created_dt.year,
month=created_dt.month,
day=created_dt.day
)
)
ts = int(utcdt.timestamp())
props = SimplePublicObjectInput({"last_booking": str(ts)})
return client.crm.companies.basic_api.update(
hs_id, simple_public_object_input=props
)
this returns this error:
{"status":"error",
"message":"Property values were not valid: [{\"isValid\":false,\"message\":\"1570233600 is at 4:10:33.600 UTC, not midnight!\"...
}
Ah, the answer was right there. Python timestamp returns the time in seconds, and HubSpot expects milliseconds. I just had to multiply by 1000:
ts = int(utcdt.timestamp()*1000)
now all looks good.
did you try adding hours and minutes to your datetime call
datetime(
year=created_dt.year,
month=created_dt.month,
day=created_dt.day,
hour=0,
minute=0
)
Use the Hubspot supported "sanetime" module: https://github.com/HubSpot/sanetime
Then to get a date:
yourdate = datetime.datetime.date()
hubspot_date = sanetime.time(yourdate )
Or if you do not want a dependency:
#convert datetime to UTC
your_utc_datetime = your_datetime.astimezone(pytz.UTC)
#replace time with midnight
your_utc_date_midnight = your_utc_datetime.replace(hour=0,minute=0,second=0, microsecond=0)
# convert to epoch (Python 3.3+)
your_hubspot_date = your_utc_date_midnight.timestamp()*1000

Subtract datetime in python, understanding formats

Given I have a timestamp:
date_time_str = '2019-09-10T13:48:06+0200'
How can I calculate the time difference between the current time and this datetime?
I've got it so far with an impression of strong wrongdoing - this should be possible in a far simpler way:
from datetime import datetime, timezone
import time
date_time_str = '2019-09-10T13:48:06+0200'
format = '%Y-%m-%dT%H:%M:%S%z'
date_time_obj = datetime.strptime(date_time_str, format)
now = datetime.now()
now_time = now.strftime(format)
print(now_time)
now=datetime.strptime(datetime.fromtimestamp(int(time.time()), tz=timezone.utc).isoformat(), format)
print("now is: %s" % now)
print(now-time_obj)
The above program does not work because the current time comes out in a slightly different formatting:
'2019-09-10T15:56:11+00:00'
That is, if you run the above script for example Python 3.6.5, you get the error:
ValueError: time data '2019-09-10T18:18:09+00:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
The mismatch is in the timezone format, "+00:00" vs. "+0200".
You can use datetime.now() to get the current datetime in utc:
# Same as your code
from datetime import datetime, timezone
date_time_str = '2019-09-10T13:48:06+0200'
format = '%Y-%m-%dT%H:%M:%S%z'
date_time_obj = datetime.strptime(date_time_str, format)
# Added:
print(datetime.now(tz=timezone.utc))
# 2019-09-10 18:35:48.066548+00:00
print(datetime.now(tz=timezone.utc) - date_time_obj)
# 6:47:42.066548

'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="aspeksnijder#outlook.com")
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?
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.
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.
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
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))
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.

How can I generate POSIX values for yesterday and today at midnight in Python?

I've been struggling to determine how I can generate a POSIX (UNIX) time value for today and yesterday (midnight) via Python. I created this code, but keep stumbling with how to convert them to a POSIX value:
from datetime import datetime, timedelta
import time
today_string = datetime.now().strftime('%Y-%m-%d 00:00:00')
yesterday_string = (datetime.now() - timedelta(0)).strftime('%Y-%m-%d 00:00:00')
today = datetime.strptime(today_string, '%Y-%m-%d %H:%M:%S')
yesterday = datetime.strptime(yesterday_string, '%Y-%m-%d %H:%M:%S')
print time.mktime(today).timetuple()
This code yields an exception:
TypeError: argument must be 9-item sequence, not datetime.datetime
At this point, I'm at my wits end. Any help you can provide is appreciated.
You should apply the timetuple() method to the today object, not to the result of time.mktime(today):
>>> time.mktime(today.timetuple())
1345845600.0
By the way, I'm wrong or yesterday will be equal to today in your code?
edit:
To obtain the POSIX time for today you can simply do:
time.mktime(datetime.date.today().timetuple())
#Bakuriu is right here. But you are making this overcomplex.
Take a look at this:
from datetime import date, timedelta
import time
today = date.today()
today_unix = time.mktime(today.timetuple())
yesterday = today - timedelta(1)
yesterday_unix = time.mktime(yesterday.timetuple())
Since the date object doesn't hold time, it resets it to the midnight.
You could also replace the last part with:
yesterday_unix = today_unix - 86400
but note that it wouldn't work correctly across daylight saving time switches (i.e. you'll end up with 1 AM or 23 PM).
Getting a unix timestamp from a datetime object as a string and as a float:
datetime.now().strftime('%s')
'1345884732'
time.mktime(datetime.now().timetuple())
1345884732.0

Converting datetime to POSIX time

How do I convert a datetime or date object into a POSIX timestamp in python? There are methods to create a datetime object out of a timestamp, but I don't seem to find any obvious ways to do the operation the opposite way.
import time, datetime
d = datetime.datetime.now()
print time.mktime(d.timetuple())
For UTC calculations, calendar.timegm is the inverse of time.gmtime.
import calendar, datetime
d = datetime.datetime.utcnow()
print calendar.timegm(d.timetuple())
Note that Python now (3.5.2) includes a built-in method for this in datetime objects:
>>> import datetime
>>> now = datetime.datetime(2020, 11, 18, 18, 52, 47, 874766)
>>> now.timestamp() # Local time
1605743567.874766
>>> now.replace(tzinfo=datetime.timezone.utc).timestamp() # UTC
1605725567.874766 # 5 hours delta (I'm in UTC-5)
In python, time.time() can return seconds as a floating point number that includes a decimal component with the microseconds. In order to convert a datetime back to this representation, you have to add the microseconds component because the direct timetuple doesn't include it.
import time, datetime
posix_now = time.time()
d = datetime.datetime.fromtimestamp(posix_now)
no_microseconds_time = time.mktime(d.timetuple())
has_microseconds_time = time.mktime(d.timetuple()) + d.microsecond * 0.000001
print posix_now
print no_microseconds_time
print has_microseconds_time
Best conversion from posix/epoch to datetime timestamp and the reverse:
this_time = datetime.datetime.utcnow() # datetime.datetime type
epoch_time = this_time.timestamp() # posix time or epoch time
this_time = datetime.datetime.fromtimestamp(epoch_time)
It depends
Is your datetime object timezone aware or naive?
Timezone Aware
If it is aware it's simple
from datetime import datetime, timezone
aware_date = datetime.now(tz=timezone.utc)
posix_timestamp = aware_date.timestamp()
as date.timestamp() gives you "POSIX timestamp"
NOTE: more accurate to call it an epoch/unix timestamp as it may not be POSIX compliant
Timezone Naive
If it's not timezone aware (naive), then you'd need to know what timezone it was originally in so we can use replace() to convert it into a timezone aware date object. Let's assume that you've stored/retrieved it as UTC Naive. Here we create one, as an example:
from datetime import datetime, timezone
naive_date = datetime.utcnow() # this date is naive, but is UTC based
aware_date = naive_date.replace(tzinfo=timezone.utc) # this date is no longer naive
# now we do as we did with the last one
posix_timestamp = aware_date.timestamp()
It's always better to get to a timezone aware date as soon as you can to prevent issues that can arise with naive dates (as Python will often assume they are local times and can mess you up)
NOTE: also be careful with your understanding of the epoch as it is platform dependent

Categories

Resources