I am gathering data on a device, and after every second, I update a count and log it. I am now processing it, and am new to python, so I had a question as to whether it was possible to convert a numbered array [0,1,2,3,4,...1091,1092,1093,...] into a timestamp [00:00:01, 00:00:02, 00:00:03, 00:00:04, ... 00:18:11, 00:18:12, 00:18:13,...] for example.
If you could please lead me in the right direction, that would be very much appreciated!
p.s. In the future, I will be logging the data as a timestamp, but for now, I have 5 hours' worth of data that needs to be processed!
import datetime as dt
timestamp=[0,1,2,3,4,5,1092,1093]
print([dt.timedelta(seconds=ts) for ts in timestamp])
Happy Coding
If all you have is seconds, then you can just do simple arithmetic to convert them to minutes and hours:
inp = [0, 1, 2, 3, 4, 1091, 1092, 1093]
outp = [f'{secs // 3600:02}:{(secs // 60) % 60:02}:{secs % 60:02}' for secs in inp]
print(outp)
# ['00:00:00', '00:00:01', '00:00:02', '00:00:03', '00:00:04', '00:18:11', '00:18:12', '00:18:13']
Here, I use a list comprehension and, for each secs in the input, create a format string:
hours is secs // 3600 (that's integer floor division), because one hour is 3600 seconds
Minutes is (secs // 60) % 60 (this incorporates the modulo operator, which displays the remainder of secs // 60 after dividing it by 60 again). One minute is 60 seconds, but more than 60 minutes would be an hour, so we need to make sure to 'roll over' the counter every 60 minutes (which is what the mod is for).
Seconds is, of course, secs % 60, because a minute has 60 seconds and we want the counter to roll over.
The format string starts with f', and anything inside {} is an instruction to evaluate whatever's inside it, and insert that into the string. The syntax is {expression:format}, where display is an optional instruction for how to format the data (i.e. not just printing it out). And format can get complicated (look up a python f-string tutorial if you're curious about the specifics), but suffice it to say that in this case we use 02, which means that we want the output to be two characters in length, and padded with zeroes in case it's less than that.
Related
So, I'm interested in printing as many numbers as possible in 9 seconds then printing a -1 at the 10th second. I have a while loop to print -1 every 10 seconds and a while loop to print any random number between 0 and 10 every 9 seconds. I am doing like this.
My problem is two-fold:
I'm not sure how to create a loop which can print as many possible numbers (depending on computing speed) in 9 seconds
I'm not sure how to put that together with the loop to print -1 every 10 seconds.
Thanks so much everyone!
You could use time module of python for this purpose. Check the below code for reference :
import time
import random
# Time for which you want the loop to run
time_to_run = 25
# Stores the future time when the loop should stop
loop_for_x_seconds = time.time() + time_to_run
start_time = time.time()
multiplier = 1 # print -1 at 10 second, increment it, so next one will be at 10*multiplier = 20 and so on...
# Loop until current time is less than the time we want our loop to run
while time.time() < loop_for_x_seconds:
# The below condition will help print -1 after about every 10s
if (time.time()-start_time)>=10*multiplier:
print(-1)
multiplier+=1
# Commented below just for purpose of showing output of -1 every 10s. Uncomment and use to get random ints printed
#else:
#print(random.randint(1,10))
Output :
-1
-1
The above code will print -1 after every 10 seconds approximately. I could have done (time.time()-start_time)%10==0 ,but this condition would rarely have been evaluated to True.
So, I went with (time.time()-start_time)>=10*multiplier . This code would print -1 after every 10s elapses ( with a difference of few milliseconds ).
You don't need to use time.sleep(10) as you showed in the image, since that would just be like pausing the loop. However, you want to continuously run the loop printing -1 every 10s and random integers other times. So the above code would serve your purpose.
Hope this helps !
I'm trying to convert a string containing a time ("%H:%M:%S.%f") to an int of the equivalent milliseconds. The complication is, the time is the output from FFmpeg, it's a point in the audio file. I need to get the number of milliseconds the time in the string represents. The timestamp method in DateTime is milliseconds from epoche, without another time stamp from when I began, this is no good.
For example:
t = "00:05:52.654321"
should be converted to:
i = 352654321
What is the best way to accomplish this?
This is how I figured out to do it.
def _convert_string_to_int(self, s) -> int:
begin = datetime.datetime(1900,1,1)
end = datetime.datetime.strptime(s, self._ffmpeg_format_string)
return int((end - begin).total_seconds() * 1000000)
It just feels really unnecessary to use timedelta like that.
Since timestamps are relative to the Unix Epoch (1970-01-01) you can make a datetime object from your time by prepending that date to it and then getting the timestamp of the resultant object to get the time string converted to seconds . Since python timestamps are floating point representations of seconds since the epoch, you will need to multiply by 1000 and convert to integer to get the number of milliseconds:
from datetime import datetime
t = "00:05:52.654321"
d = datetime.strptime('1970-01-01 ' + t, '%Y-%m-%d %H:%M:%S.%f')
print(int(d.timestamp()*1000))
Output:
352654
If you actually want microseconds, multiply by 1000000 instead.
As an alternative, you can split the time string on : and sum the parts, multiplying by 60 or 3600 to convert the hour and minute parts to seconds:
t = "00:05:52.654321"
millisecs = int(sum([float(v) * 1000 * 60 ** (2 - i) for i, v in enumerate(t.split(':'))]))
print(millisecs)
Output:
352654
Again, if you want microseconds, just multiply by 1000000 instead of 1000.
A number of milliseconds is inherently a time interval, so there is good reason why datetime.timedelta instances have a total_seconds method while datetime.datetime, datetime.date and datetime.time do not have one.
In principle you could use datetime.datetime.time(end) to get an object with properties including hour, minute, second and microsecond, and then use these to construct an arithmetic expression for the elapsed time since midnight on the same day. However, the supported way to handle time intervals like this is precisely the timedelta approach that you are already using.
I am reading in time stamps as strings from a service that is UNIX time formatted in Nano seconds. This introduces an obvious problem in that I can't conduct standard operations to normalize the strings to seconds given how large they are. An example of one of these strings is '1589212802642680000' or 1.58921E+18 in scientific notation.
I was trying something like this: convert_fills_df['timeStamp'] = convert_fills_df.timeStamp.apply(lambda x: UNIX_EPOCH + (float(x)/1000000000)). But I overflow the float object when I try this; is there a string operation I can do without losing precision down to the second? Nanoseconds for my purpose are not necessary (though I appreciate their thoroughness). If I could keep the nanoseconds that's great too, but it is not a necessity.
I would like to just convert the time to a human readable format in 24 hour clock format.
The first 10 digits represents the seconds, the subsequent digits represent milli, micro & nanosecond precision
To keep all the information you can insert . at the right position, and pass the string to pd.to_datetime
df = pd.DataFrame({'ns': ['1589212802642680000']})
pd.to_datetime(df.ns.str[:10] + '.' + df.ns.str[10:], unit='s')
# outputs
0 2020-05-11 16:00:02.642679930
Name: ns, dtype: datetime64[ns]
I got the code to do what I want, yet I feel its hardcoded than an actual solution. Any suggestions on how I could adjust the Hours, Minutes, Seconds variables to be more clear to the reader?
Input = int(input("Seconds: "))
Hours = Input // (60*60)
Minutes = Input//(60) - (Hours*60)
Seconds = Input - (Minutes*60) - (Hours*60*60)
print(Hours,"Hours",Minutes,"Minutes",Seconds,"Seconds")
Use modulos instead of division. They're a little confusing at first, but they're really awesome.
def convert(seconds):
secs = seconds%60
mins = (seconds//60)%60
hrs = (seconds//3600)
return (secs,mins,hrs)
From a code optimization standpoint, my code does a total of four arithmetic operations, whereas yours runs through 10. Additionally, the whole (Hours * 60) thing is a little difficult to understand.
That's not to say your code is bad, just a little unclear. Though readability counts, your code is not so illegible as to be impossible to understand.
Constants help readability. Also using modulo helps:
SEC_PER_MIN = 60
SEC_PER_HOUR = SEC_PER_MIN * 60
secs = int(input("Seconds: "))
hours = secs // SEC_PER_HOUR
remaining_seconds = secs % SEC_PER_HOUR
mins = remaining_seconds // SEC_PER_MIN
remaining_seconds %= SEC_PER_MIN
print(f"{hours} Hours, {mins} Minutes, and {remaining_seconds} Seconds")
or you can abuse the time module and have it handle all the logic:
import time
secs = int(input("Seconds: "))
result = time.strftime('%H Hours, %M Minutes, %S Seconds', time.gmtime(secs))
print(result)
syncClockTime :: TimeZone -> UTCTime -> Pico -> Pico
syncClockTime zone time secondTo = do
let (TimeOfDay hour minute secondFrom) = localTimeOfDay $ utcToLocalTime zone time
if secondTo > secondFrom then
secondTo - secondFrom
else
60 + secondTo - secondFrom
I have a couple of questions related to the above code
is there a way to directly extract the seconds secondFrom from the UTCTime without converting it to local time and without specifying a time zone? (if yes: how? if no: why?)
How to actually make the running thread/task to asynchronously sleep for the above found number of seconds?
Question 2 is simple: you can make your Haskell process sleep for a specified number of microseconds using delay.
If I understand your Question 1, you want to be able to specify, say 30 seconds, and wait until the next time the system clock is 30 seconds past the minute. So if you call your function at 13:23:27 it will wait 3 seconds until 13:23:30, but if you called it at 13:23:33 then it will wait 57 seconds until 13:24:30.
That is a matter of doing arithmetic on the number of seconds. I would suggest you take the current Posix time using getPOSIXTime. This returns a NominalDiffTime, which is an instance of Real and RealFrac, so normal arithmetic works fine. The code you want is:
t <- getPOSIXTime
let secs = t - fromIntegral (floor (t/60) * 60)
Once you have the number of seconds past the minute you can figure out how long to wait until your target time.