I am expecting the following code will return 0 but I get -3600, could someone explains why? and how to fix it? thanks
import datetime
import time
ts = time.mktime(time.gmtime(0))
print time.mktime(datetime.datetime.fromtimestamp(ts).timetuple())
time.mktime converts a time tuple in local time to seconds since the Epoch. Since time.gmtime(0) returns GMT time tuple, and the conversion assumes it was in your local time, you see this discrepancy.
Related
I'm having a hard time converting numpy.timedelta64, which is directional, into a time span, which is not directional. I don't see any instructions in the docs
The .abs function does not seem to work on timedelta values
Use np.abs(x) or abs(x), both work fine.
I encountered this issue but found the solution after a bit of research. I have posted my answer below to show my findings. If anyone has alternative suggestions please post them.
I needed to convert a datetime.datime object to a Unix timestamp. I tried using the datetime.timestamp. I found the result was 1 hour behind what I expected. I was able to replicate this issue with the following.
from datetime import datetime, timestamp
dt = datetime.utcfromtimestamp(1438956602.0)
dt now equals datetime.datetime(2015, 8, 7, 14, 10, 2)
Then:
dt_stamp = datetime.timestamp(dt)
Which gives dt_stamp = 1438953002.0 (which is different from our original timestamp). If we convert it back to datetime
datetime.utcfromtimestamp(dt_stamp)
We get:
datetime.datetime(2015, 8, 7, 13, 10, 2)
Which is an hour earlier than our original time.
For context I am using Python 3 and based in Britain where we're currently using British summer time (1 hour ahead of UTC).
My solution can be found below. If you think I have missed anything from my explanation or there's a better solution, please post your own answer.
I met the same problem recently, my case is that part EDF recording from one hostipal in UK have one hour bias, which is considered due to British summer time.
Following is the solution to my case.
from datetime import datetime as dt
Please use
dt = dt.utcfromtimestamp(#YOUR_TIME_STAMP)
INSTEAD of
dt = dt.fromtimestamp(#YOUR_TIME_STAMP)
The cause for this difference is actually shown in the
datetime.timestamp documentation.
Naive datetime instances are assumed to represent local time and this method relies on the platform C mktime() function to perform the conversion. Since datetime supports wider range of values than mktime() on many platforms, this method may raise OverflowError for times far in the past or far in the future.
Because I am in UTC+1 (during British summer time) this is the timezone datetime.timestamp uses to calculate the timestamp. This is where the mistake comes in. The documentation recommends a few ways to deal with this. I went with the following.
from datetime import datetime, timestamp
dt = datetime.utcfromtimestamp(1438956602.0)
dt_stamp = datetime.timestamp(dt.replace(tzinfo=timezone.utc))
By adding .replace(tzinfo=timezone.utc) to the end of dt it specifies that this is done in the UTC timezone. datetime.timestamp then knows to use the UTC time rather than whatever timezone my machine is running.
People in America or other parts of the world will encounter this issue if not using the UTC timezone. If this is the case you can set tzinfo to whatever your timezone is. Also note that datetime.utcfromtimestamp is also clearly designed for people using the UTC timezone.
I think you need a so called aware datetime object. Aware means it nows the time difference you have:
datetime.fromtimestamp(timestamp, timezone(timedelta(hours=1)))
Try it with that line of code, where timestamp is your Unix timestamp.
Python methods to convert ISO 8601 time format to UNIX timestamp (epoch) and back again without losing fractional seconds?
I found several examples, but all the examples seem to drop the fractional seconds at some point in the conversion. Example below...
The issue seems to be the initial conversion to UNIX timestamp (epoch). Code below.
def ISO8601ToEpoch(theString):
from datetime import datetime
import calendar
return calendar.timegm(datetime.strptime(theString, "%Y-%m-%dT%H:%M:%S.%f").timetuple())
def EpochToISO8601(theEpoch):
from datetime import datetime
return datetime.fromtimestamp(theEpoch).isoformat()
#
print 'Original Time {0}'.format('2018-04-27T04:19:51.050937')
theTime=ISO8601ToEpoch('2018-04-27T04:19:51.050937')
print 'Time {0}'.format(theTime)
print 'Original Time {0}'.format(EpochToISO8601(theTime)
This results as...
Original Time 2018-04-27T04:19:51.050937
Time 1524802791
Original Time 2018-04-27T04:19:51
Is there a way to get timetuple to not hack the fractional seconds?
The problem here is that you're converting a datetime—which understands microseconds—into a timetuple—which doesn't.1
The obvious fix is just to not do that.
If you want to convert a datetime object to a timestamp, just use the timestamp method, the same way you already use the fromtimestamp classmethod to go the other way.
1. You might be able to trick a timetuple into holding a float instead of an int for seconds. But then you'd be breaking the invariants of the type. And, more importantly, defeating the entire purpose of the type, which is to be identical to a 1980s-style C struct tm. And likely also breaking the timegm function, which probably just calls the C function of the same name. (Most of the time module is a thin wrapper around C's <time.h>, as opposed to datetime, which is a friendly module designed for Python.) And then timegm is documented to return an integral type, so even if you got that far, it would all be for nothing.
I think this is correct... but if not I am sure someone will point out what I missed.
>>> import datetime as datetime
>>> import dateutil.parser
>>> import time
# Create a sample UNIX timestamp...
>>> t=time.time()
>>> t
1478266530.573583
# Convert the time stamp sample to ISO format...
>>> i=datetime.datetime.utcfromtimestamp(t).isoformat()
>>> i
'2016-11-04T13:35:30.573583'
# Convert ISO format to UNIX time stamp...
>>> d=dateutil.parser.parse(i)
>>> d
datetime.datetime(2016, 11, 4, 13, 35, 30, 573583)
>>> s=(time.mktime(d.timetuple())*1e3+d.microsecond/1e3)/1e3
>>> s
1478266530.5735831
It is not a perfect conversion given the number of fractional digits of the resulting timestamp but close enough for my need. I am sure the ISO format is a point of debate, but the format matches the typical format I expect to encounter, this is of course the lack of the 'Z' qualifier.
I have to convert date and time returned by ls of rsync into Unix epoch time float as returned by time.time().
For me here at this moment it looks like:
2017/05/24 hh:mm:ss.
But as far as I know it can vary from machine to machine as rsync uses ssh and native ls, I expect through it.
Is there any easy way to universally convert most common human readable date and time back to the Unix time float?
To be clear. I want to be able to convert any textual representation of D and T into the float.
If datetime can do this I cannot find how at the moment.
You need to use time.strptime first and then calendar.timegm
there are different options depending if you want to convert to local time or UTC time. Have a look to the documentation for that.
To get the float part, you need to input hours, minutes, seconds and milliseconds. In your example, you give only the year, month and day, so the rest is supposed to be zero i.e. no milliseconds thus no float part.
Here a minimal example:
import calendar, time
t = time.strptime('2017/05/24', '%Y/%m/%d')
epoch = calendar.timegm(time.struct_time(t))
print(epoch)
1495584000
I intend to find the time difference between two time variables in seconds. The issue here is that I am referring to time in a different zone. I have managed to find a solution, but it is a mix of pandas.datetime function and python datetime library. I guess, the objective can be achieved with just pandas/numpy alone and with fewer lines of code. below is my code, appreciate any guidance on how can i achieve the final_output more efficiently.
import pandas as pd
from datetime import timedelta
local_time = pd.to_datetime('now').tz_localize('UTC').tz_convert('Asia/Dubai')
t1 = timedelta(hours=local_time.now('Asia/Dubai').hour, minutes=local_time.now('Asia/Dubai').minute)
t2 = timedelta(hours=9, minutes=14)
final_output = (t2 - t1).seconds
You may want to convert both times to UTC, then find the difference. Programmers usually like to work with UTC until the time reaches the front end.