Converting human readable date and time into Unix time float - python

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

Related

Converting user input to time and substracting it from main time

I am doing some project for myself and i am stuck with an assignment.
I have strict time that's 30min
I have a user that gives an input like: 24008
I need to convert an user input to time(2min:40sec:08milisec) and substract it from main time.
I tried time.strftime('%M:%S:%f', 1800) to show main Time (30min) like 30:00:00 but i don't seem to get the datetime or time imports and how do they work. Same with user input.
Can anyone with a kind heart would guide me to a right path on how to get this logic done and by what function?
I can't share a code because i don't have any working logic for this one.
A datetime.time object would probably be the best data structure to use for this
Your initial value of 30 minutes would be defined like this
import datetime
strict_time = datetime.time(minutes=30)
If the user input you gave as an example will always be the input format then it becomes a little hard to parse as python's datetime module's strptime behaviour does not handle 2-digit millisecond inputs and 1 digit minute inputs. If the input format is exactly the same (5 digits with 1 minute digit, 2 second digits and 2 millisecond digits) then the following would work
user_input = '24008'
input_time = datetime.timedelta(
minutes=int(user_input[0]),
seconds=int(user_input[1:2]),
microseconds=int(user_input[3:4])
)
new_time = strict_time - input_time

datetime.timestamp() loses an time (an hour)

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.

Convert ISO 8601 time format to UNIX timestamp (epoch) and back again without losing fractional seconds?

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.

Use current time of the day as an integer in python

I am looking to create an if then statement that involves the current time of the day. For example I want something like if it is past 2pm then do this function.
I have tried using the time module but I can't seem to find a way to get just the time of day without the extra stuff like the date. Any help?
Here is a start, and I think it'll be enough for you to get to the answer and use it how you need.
import time
print(time.strftime("%Y-%m-%d %H:%M"))
print(time.strftime("I can format the date and time in many ways. Time is: %H:%M"))
Output (when I ran it):
2017-06-21 10:40
I can format the date and time in many ways. Time is: 10:40

How to generate a fixed-length hash based on current date and time in Python?

I want to generate a fixed-length (say 10 characters) hash based on current date & time. This hash will be append to names of the uploaded files from my users. How can I do that in Python?
Batteries included:
Python3
import hashlib
import time
hashlib.sha1().update(str(time.time()).encode("utf-8"))
print(hashlib.sha1().hexdigest())
print(hashlib.sha1().hexdigest()[:10])
Python2
import hashlib
import time
hash = hashlib.sha1()
hash.update(str(time.time()))
print hash.hexdigest()
print hash.hexdigest()[:10]
I think my comment is a reasonable answer so I am going to post it. The code uses the python time() function to get the number of seconds since the unix epoch:
import time
import datetime
ts = int(time.time()) # this removes the decimals
# convert the timestamp to a datetime object if you want to extract the date
d = datetime.datetime.fromtimestamp(ts)
The time stamp is currently a 10 digit integer that can easily be converted back to a datetime object for other uses. If you want to further shrink the length of the timestamp you could encode the number in hexadecimal or some other format. ie.
hex(int(time.time()))
This reduces the length to 8 characters if you remove the 0x prefix
EDIT:
In your comment you specified that you don't want people to figure out the original date so I would suggest doing something like:
hex(int(time.time() + 12345))[2:] #The [2:] removes the 0x prefix
Just chose a number and remember to subtract it when you are trying to extract the timestamp. Without knowing this number the user would have a very difficult time inferring the real date from your code.
int(stamp,16) - 12345
import time
'{0:010x}'.format(int(time.time() * 256))[:10]
Check out strftime for python. You can format the date/time string any number of ways to get the 'look' you want.
What about changing the base of current milliseconds since epoch. For example, in JavaScript, changing to base 36:
Date.now().toString(36)
Results in :
"jv8pvlbg"
That should be a safe hash, up to milliseconds, respect date order and smaller than 10.
The only thing is that is not safe, but in your case security is not important right?
Sorry I don't have the answer for python, but it should by straightforward and should nor require any library. My two cents.

Categories