Convert Unix Timestamp to human format in Django with Python - python

I'd like to a convert unix timestamp I have in a string (ex. 1277722499.82) into a more humanized format (hh:mm:ss or similar). Is there an easy way to do this in python for a django app? This is outside of a template, in the model that I would like to do this. Thanks.
edit
I'm using the python function time.time() to generate the timestamp. According to the doc:
time.time()
Return the time as a floating point number expressed in seconds
since the epoch, in UTC. Note that
even though the time is always
returned as a floating point number,
not all systems provide time with a
better precision than 1 second. While
this function normally returns
non-decreasing values, it can return a
lower value than a previous call if
the system clock has been set back
between the two calls.

import datetime
datestring = "1277722499.82"
dt = datetime.datetime.fromtimestamp(float(datestring))
print(dt)
2010-06-28 11:54:59.820000

Related

Converting seconds to minutes using datetime.timedelta

I am having trouble understanding a simple timedelta function.
In the code below, it is supposed to convert total_travel_time provided in seconds to minutes. Can someone briefly explain the logic behind the (seconds = total_travel_time) part?
Is it telling python that the total_travel_time is in seconds?
How come python understands to convert it to minutes even without "minutes" somewhere in the code?
total_travel_time = df['Trip Duration'].sum()
print("Total travel time: {}".format(str(datetime.timedelta(seconds = total_travel_time))))
Your code has some parts that aren't really relevant to your question.
It boils down to this:
import datetime
n = 120
print(datetime.timedelta(seconds=n))
Note that even the str() bit is superfluous, since passing it to print() already requires conversion to string anyway
Result:
0:02:00
It's not converting anything to minutes, it's constructing a timedelta object, being given a number of seconds. In this case, that happens to include a number of minutes. But depending on the number of seconds, it could be anything.
When printing a timedelta, Python needs to turn it into a string of characters (because that's all we can read) and it chooses the standard HH:mm:ss format (unless it's more than a day, then it'll print the number of days separately).
To get the actual number of minutes, you'd actually start with the seconds (that are accessible directly on the timedelta object):
print(datetime.timedelta(seconds=n).seconds // 60)

Python: UTC vs local timestamp

Why the followings return different timestamp? Is it because datetime.utcnow() doesn't have a timezone? It looks to me that tzinfo=utc is redudant, so I am probably not getting what is utcnow() and how an UTC number could not have a timezone. I guess there is a reason, so please enlight me :)
from datetime import datetime
from pytz import utc
local_seconds = int(datetime.utcnow().timestamp())
utc_seconds = int(datetime.utcnow().replace(tzinfo=utc).timestamp())
My goal is to get the UTC timestamp. It looks like the first method returns the local timestamp (correct me if I am wrong)
EDIT:
Where I live the timezone is GMT-5. In fact:
(utc_seconds-local_seconds)/3600 # is equal to -5.0
Following two statements would always return different result.
local_seconds = int(datetime.utcnow().timestamp())
utc_seconds = int(datetime.utcnow().replace(tzinfo=utc).timestamp())
Output:
1585584790
1585604590
You ask why? Because, by the time first statement executes, there is some time spent during execution and now the second statement would fetch you different result because datetime.utcnow() for 2nd statement has changed.
What I assume is, you want to see if both operations would give the same result or not? They definitely would have given the same results :
Had you provided them the same input?
Had you performed the similar operation from a common library.
To solve 1. change your code like this.
same_time_input = datetime.utcnow()
local_seconds = int(same_time_input.timestamp())
utc_seconds = int(same_time_input.replace(tzinfo=utc).timestamp())
Still the output would not be same, because you are using an external library, and the replace function is not working as you expected.
If you printout the tzinfo from same_time_input, you would see that it doesn't have any timezone info reason of which can be read here. --> Why does datetime.datetime.utcnow() not contain timezone information?
print(same_time_input.tzinfo)
Now, you are trying to give it a timezone info using a separate library which has different implementation internally resulting in slightly off results.

Why does converting timezones (and to unix timestamps) behave inconsistently in Pandas?

I'm parsing and manipulating some dates and times which, for reasons of interoperability with other systems, also need to be stored as UNIX (epoch) timestamps. In doing so, I'm seeing some weird behavior from pandas' Timestamp.tz_convert(), and then in its Timestamp.strftime() behavior in casting to epoch time, that makes me doubt my understanding of what should be going on.
The times I'm working with are in the US/Eastern timezone, but of course, epoch time is UTC, so my approach had been to cast to UTC since most conversions to/from UNIX timestamps assume that a tz-naive DateTime is in UTC. Let's leave aside whether doing that conversion is absolutely necessary to get valid timestamps; here's what I'm seeing that's problematic:
1. Using Timestamp.tz_convert() to change the timezone representation of a timestamp (i.e., a universal point in time) also changes the UNIX timestamp when you convert using Timestamp.strftime().
2. The differences in those timestamps don't even correspond to the proper hour differences between US-Eastern and GMT.
Here's some basic interactive-mode python to illustrate:
>>> import pytz
>>> from pytz import timezone
>>> import pandas as pd
>>> dtest = pd.to_datetime("Sunday, July 28, 2018 10:00 AM", infer_datetime_format=True).replace(tzinfo=timezone('America/New_York')) # okay, this should uniquely represent a point in time
>>> dtest
Timestamp('2018-07-28 10:00:00-0400', tz='America/New_York') # yup, that's the time - 10AM at GMT-0400.
>>> dtest2 = dtest.tz_convert('UTC') # convert to UTC
>>> dtest2
Timestamp('2018-07-28 14:00:00+0000', tz='UTC') # yup, same point in time, just different time zone now
>>> dtest.strftime('%s') # let's convert to unix time - this looks right
'1532786400'
>>> dtest2.strftime('%s') # should be the same, but it's not. WTF?
'1532804400'
The timestamps look like they are describing things equivalently: one is 10 AM at GMT-0400, the other is 2 PM at GMT+0000, a difference of 4 hours of clock time, as expected. They're both, of course, timezone-aware. But then converting them to UNIX timestamps yields
(A) different numbers, and even worse,
(B) numbers that differ by 5 hours (18000 seconds = 5 * 60 * 60) rather than 4, so I can't even assume that strftime() is merely ignoring timezone.
I'm using https://www.epochconverter.com/ to validate any timestamps as I sanity-check this, so that's a possible point of being misled. But according to that site,
1532786400 = 2018-07-28T10:00 -0400, and
1532804400 (that last result) = 2018-07-28T15:00 -0400, or 7pm GMT, a difference of 5 hours.
There are lots of questions on the subject of casting pandas Timestamps FROM a UNIX timestamp, but very little on questions casting TO epoch time. I can think of 2 possible explanations:
(1) tz_convert() is pulling some environment variable on my system that says I'm GMT -0500 and using that in the conversion process, in spite of that being irrelevant to converting between timezone-aware timestamps, and in so doing is actually changing the underlying point in time being represented. Or:
(2) Timestamp.strftime() is bugged and either ignoring the timezone parameter of a tz-aware timestamp or doing something truly bizarre when asked for a '%s' formatting parameter.
All advice greatly appreciated.

Python timestamp in precision of milliseconds

I need to output a timestamp for a .csv file of the current time in milliseconds. Right now I have:
localTime = time.localtime(time.time())
now = time.localtime(time.time())
currTime = time.time()
now = time.strftime("\"%Y-%m-%d %H:%M:%S.%f\"", time.localtime(currTime))
doing it this way will output the timestamp in the following format:
"2017-05-09 10:13:33.%f" this obviously is not correct. Ive heard that time.time only goes as precise as a second, but have also heard that it can support microseconds. Can somebody clear this up for me or show me the proper way to format this code to get a timestamp in the needed format? (2017-05-09 10:13:33.100) for example
A quick solution would be:
t=time.time()
millis = int((t - int(t))*1000)
As you said, the problem is that time doesn't necessarily give you the precision you want[1]. datetime would be a better option:
from datetime import datetime
now = datetime.utcnow() # or datetime.now(your_timezone)
formatted = now.strftime("%Y-%m-%d %H:%M:%S.%f")
print(formatted)
[1] Both in python 2.x and 3.x, according to the docs:
Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a lower value than a previous call if the system clock has been set back between the two calls.

Python datetime precision

I have a Google App Engine datetime property which I populate with x.date = datetime.datetime.now(). I do a lot of comparisons between dates, and after much debugging, it turns out my client device sends dates out with less precision than a Python date, which caused a terrible mess.
Here is what Python generates:
2012-08-28 21:36:13.158497 with datetime.datetime.now(), but what I want is 2012-08-28 21:36:13.158000 (notice the three zeros at the end.)
How can I achieve this? (keep in mind, I'm not trying to format strings or anything. I want to format a date object.)
I guess one way would be to format it into a string with desired precision, like this:
dateString = date.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
and then back to a date object. But there's got to be a better way.
dt = dt.replace(microsecond = (dt.microsecond / 1000) * 1000)
This will truncate the last 3 digits. Proper rounding is a little more complicated due to the possibility that it might round to 1000000 microseconds.

Categories

Resources