Python Time Math - python

I want to write a program that allows the user to enter in a start time hour, end time hour, and number of divisions.
So they might enter 9, 10, and 4 which should mean a start time of 9:00AM, end of 10:00AM and to split the range 4 times, resulting in an output of 9:00, 9:15, 9:30, 9:45.
I've tried using the time module and datetime, but cannot get the addition of time to work. I do not care about date.
I can calculate the time split, but the actual addition to the start time is evading me.
I have a hodge-podge of code, and the following is mostly me experimenting trying to figure out how to make this work. I've tried adding the minutes, tried converting to seconds, delved into datetime, tried the time module, but can't seem to get it to work. There are plenty of examples of how to "add 15 minutes to now" but the issue is I don't want to start at the "now", but rather let the user decide start time.
Thank you.
time_start = "9"
time_end = "10"
time_split = "4"
if len(time_start) == 1:
time_start = "0" + str(time_start) + ":00"
else:
time_start = str(time_start) + ":00"
if len(time_end) == 1:
time_end = "0" + str(time_end) + ":00"
else:
time_end = str(time_end) + ":00"
print time_start
print time_end
s1 = time_start + ':00'
s2 = time_end + ':00'
FMT = '%H:%M:%S'
tdelta = datetime.strptime(s2, FMT) - datetime.strptime(s1, FMT)
divided = tdelta / int(time_split)
print tdelta
print divided
s3 = str(divided)
print "s1 time start: " + str(s1)
print "s2 time end: " + str(s2)
print "s3 time divided: " + str(s3)
ftr = [3600,60,1]
add_seconds = sum([a*b for a,b in zip(ftr, map(int,s3.split(':')))])
print "s3 time divided seconds: " + str(add_seconds)
print "time delta: " + str(tdelta)

EDIT: I did a small bit of research and found a much better solution that elegantly handles resolution to the millisecond. Please implement this code instead (though I will save the old code for posterity)
import datetime
start_time = 9 # per user input
end_time = 10 # per user input
divisions = 7 # per user input
total_time = end_time - start_time
start_time = datetime.datetime.combine(datetime.date.today(),datetime.time(start_time))
end_time = start_time + datetime.timedelta(hours=total_time)
increment = total_time*3600000//divisions # resolution in ms
times = [(start_time+datetime.timedelta(milliseconds=increment*i)).time()
for i in range(divisions)]
from pprint import pprint
pprint(list(map(str,times)))
# ['09:00:00',
# '09:08:34.285000',
# '09:17:08.570000',
# '09:25:42.855000',
# '09:34:17.140000',
# '09:42:51.425000',
# '09:51:25.710000']
If I were you, I'd do my math as raw minutes and use datetime.time only to save the results as something more portable.
Try this:
import datetime
start_time = 9 # per user input
end_time = 10 # per user input
divisions = 4 # per user input
total_minutes = (end_time-start_time)*60
increment = total_minutes // divisions
minutes = [start_time*60]
while minutes[-1] < end_time*60:
# < end_time*60 - increment to exclude end_time from result
minutes.append(minutes[-1] + increment)
times = [datetime.time(c//60,c%60) for c in minutes]
# [09:00:00,
# 09:15:00,
# 09:30:00,
# 09:45:00,
# 10:00:00]

Related

Calculation of business working hour in python

I would like to write a function that calculate working business hours in python, to do that I don't like to define a class and use python ready function to calculate.
I tried with following code but the code is not working well. I need to modify the code and change it for the hour instead of minutes too.
Do you have any suggestion?
def getminutes(datetime1,datetime2,worktiming=[9, 17]):
day_hours = (worktiming[1]-worktiming[0])
day_minutes = day_hours * 60 # minutes in a work day
weekends=[6, 7]
# Set initial default variables
dt_start = datetime1.datetime # datetime of start
dt_end = datetime2.datetime # datetime of end
worktime_in_seconds = 0
if dt_start.date() == dt_end.date():
# starts and ends on same workday
full_days = 0
if dt_start in [6, 7]:
return 0
else:
if dt_start.hour < worktiming[0]:
# set start time to opening hour
dt_start = datetime.datetime(
year=dt_start.year,
month=dt_start.month,
day=dt_start.day,
hour=worktiming[0],
minute=0)
if dt_start.hour >= worktiming[1] or \
dt_end.hour < worktiming[0]:
return 0
if dt_end.hour >= worktiming[1]:
dt_end = datetime.datetime(
year=dt_end.year,
month=dt_end.month,
day=dt_end.day,
hour=worktiming[1],
minute=0)
worktime_in_seconds = (dt_end-dt_start).total_seconds()
elif (dt_end-dt_start).days < 0:
# ends before start
return 0
else:
# start and ends on different days
current_day = dt_start # marker for counting workdays
while not current_day.date() == dt_end.date():
if not is_weekend(current_day):
if current_day == dt_start:
# increment hours of first day
if current_day.hour < worktiming[0]:
# starts before the work day
worktime_in_seconds += day_minutes*60 # add 1 full work day
elif current_day.hour >= worktiming[1]:
pass # no time on first day
else:
# starts during the working day
dt_currentday_close = datetime.datetime(
year=dt_start.year,
month=dt_start.month,
day=dt_start.day,
hour= worktiming[1],
minute=0)
worktime_in_seconds += (dt_currentday_close
- dt_start).total_seconds()
else:
# increment one full day
worktime_in_seconds += day_minutes*60
current_day += datetime.timedelta(days=1) # next day
# Time on the last day
if not is_weekend(dt_end):
if dt_end.hour >= worktiming[1]: # finish after close
# Add a full day
worktime_in_seconds += day_minutes*60
elif dt_end.hour < worktiming[0]: # close before opening
pass # no time added
else:
# Add time since opening
dt_end_open = datetime.datetime(
year=dt_end.year,
month=dt_end.month,
day=dt_end.day,
hour=worktiming[0],
minute=0)
worktime_in_seconds += (dt_end-dt_end_open).total_seconds()
return int(worktime_in_seconds / 60)
How can I modify the code that works with the following input ?
getminutes(2019-12-02 09:30:00,2019-12-07 12:15:00,worktiming=[9, 17])
You can use pd.bdate_range(datetime1, datetime2) to compute the number of working days. When converting worktiming to a pandas datetime, it is easy to compute the difference (in seconds) between the two datetimes:
import pandas as pd
datetime1 = "2019-12-02 09:30:00"
datetime2 = "2019-12-07 12:15:00"
def getminutes(datetime1, datetime2, worktiming=[9, 17]):
d1 = pd.to_datetime(datetime1)
d2 = pd.to_datetime(datetime2)
wd = pd.bdate_range(d1, d2) # working days
day_hours = (worktiming[1] - worktiming[0])
day_minutes = day_hours * 60 # minutes in a work day
day_seconds = day_minutes * 60 # seconds in a work day
full_days = len(wd)
day1 = datetime1[:10]
day2 = datetime2[:10]
dt1 = pd.to_datetime(day1 + " " + str(worktiming[0]) + ":00")
dt2 = pd.to_datetime(day2 + " " + str(worktiming[1]) + ":00")
ex1, ex2 = 0, 0
if day1 in wd:
ex1 = max(pd.Timedelta(d1 - dt1).seconds, 0)
if day2 in wd:
ex2 = max(pd.Timedelta(dt2 - d2).seconds, 0)
total_seconds = full_days * day_seconds - ex1 - ex2
total_minutes = total_seconds / 60
total_hours = total_minutes / 60
return int(total_minutes)
print(getminutes(datetime1, datetime2))
Output: 2370

Python Timer Cooldown Example

I'm looking for a cooldown timer for python, basically just to print days,hours,minutes,seconds left from a certain date.
Thanks very much!
You can get the counter with the help of time delta function.
import datetime
import time
future_date = datetime.datetime.now()+ datetime.timedelta(seconds=3)
while True:
curr_date = datetime.datetime.now()
rem_time = future_date - curr_date
total_seconds = int(rem_time.total_seconds())
if total_seconds > 0:
days, h_remainder = divmod(total_seconds, 86400)
hours, remainder = divmod(h_remainder, 3600)
minutes, seconds = divmod(remainder, 60)
print("Time Left: {} days, {} hours, {} minutes, {} seconds".format(days, hours, minutes, seconds))
time.sleep(1)
else:
break
sample output will be:
Time Left: 0 days, 0 hours, 0 minutes, 2 seconds
Time Left: 0 days, 0 hours, 0 minutes, 1 seconds
Try this. The module datetime is preinstalled on Python, I believe.
import datetime
while True:
print("\033[H\033[J")
present = datetime.datetime.now()
future = datetime.datetime(2022, 3, 31, 8, 0, 0)
difference = future - present
print(difference)
The format for datetime's future is: year, month, day, hour, minute, second.
Or, if you'd like to have user input:
import datetime
year = int(input('Enter the year of the end date: '))
month = int(input('Enter the month of the end date: '))
day = int(input('Enter the day of the end date: '))
hour = int(input('Enter the hour of the end date: '))
minute = int(input('Enter the minute of the end date: '))
second = int(input('Enter the second of the end date (a little tricky): '))
future = datetime.datetime(year, month, day, hour, minute, second)
while True:
print("\033[H\033[J")
present = datetime.datetime.now()
difference = future - present
if present >= future:
break
print(difference)
print('Time reached!')
You can use the seconds from a timedelta from subtracting two dates to calculate the days, hours, minutes and seconds like this:
from datetime import datetime
import time
totalSecs = 1 #So the while loop doesn't stop immidiately
while totalSecs > 0:
startDate = datetime.now() #Can be any date
endDate = datetime(2021, 12, 25)
delta = endDate - startDate
totalSecs = delta.total_seconds()
days = divmod(totalSecs, 86400)
hrs = divmod(days[1], 3600)
mins = divmod(hrs[1], 60)
seconds = divmod(mins[1], 1)
print("{:02d}:{:02d}:{:02d}:{:02d}".format(int(days[0]), int(hrs[0]), int(mins[0]), int(seconds[0]))) #Zero pad all the numbers
time.sleep(1) #Print every second.
Thank you all for your replies, i've done a mistake when i made the post. Is not from a date. Is a countdown in day,hours,minutes,seconds from a certain amount of seconds. Let's say i've got 31104000 seconds and i want to print how many days,hours,minutes,seconds left from that amount of seconds.
The code i've got now is a bit trivial and i can't print seconds in realtime.
def SecondToDHM(time):
if time < 60:
return "%.2f %s" % (time, SECOND)
second = int(time % 60)
minute = int((time / 60) % 60)
hour = int((time / 60) / 60) % 24
day = int(int((time / 60) / 60) / 24)
text = ""
if day > 0:
text += str(day) + DAY
text += " "
if hour > 0:
text += str(hour) + HOUR
text += " "
if minute > 0:
text += str(minute) + MINUTE
text += " "
if second > 0:
text += str(second) + SECOND
return text
import datetime
a = datetime.datetime.now()
"%s:%s.%s" % (a.minute, a.second, str(a.microsecond))

I am trying to sample at 100hz instead of just as quick as the program will run. How would I do that?

I have a program in which I am just printing to a csv and I want exactly 100 sample points every second but I have no clue where to start with this or how to do it!!! Please help!
from datetime import datetime
import pandas as pd
i = 0
data = []
filename = 'Data.csv'
hz = 0
count = 0
while True:
#start = process_time()
if i == 0:
Emptydf = pd.DataFrame([], columns = ['COUNT', 'TIME'])
(Emptydf).to_csv('Data.csv', index = False)
curr_time = datetime.now()
str_milli = curr_time.strftime("%f")[:2]
milliseconds = int(str_milli)
timestamp = curr_time.strftime("%H:%M:%S.%f")
datarow = {'Count': i, 'TIME' : timestamp}
#diff = curr_time - past time of 0.01 milli seconds
#if diff >= 0.01:
data.append(datarow)
#time.sleep(.006)
if i%10 == 0:
dataframe = pd.DataFrame(data)
(dataframe).to_csv('Data.csv', mode = 'a', header = False, index = False)
#print(dataframe)
data.clear()
i += 1
Here is an example that increments a counter 100 times per second:
import time
FREQ_HZ = 100.
count = 0
start_time = time.time()
try:
while True:
count += 1
time.sleep(count / FREQ_HZ - (time.time() - start_time))
except:
print("%.2f iter/second\n" % (count / (time.time() - start_time)))
To test, let it run for a bit and then hit ^C.
Basically, what you do is the following;
import time
cycletime = 0.01 # seconds
while True:
start = time.monotonic()
# << Do whatever you need to do here. >>
delta = time.monotonic() - start
if delta < cycletime: # Did we finish in time?
time.sleep(cycletime - delta) # Sleep the rest of the time.
else:
print('WARNING: cycle too long!')
Note that for such applications time.monotonic is preferred over time.time because the latter can decrease when the system clock is changed.

Calculating the amount of time left until completion

I am wondering how to calculate the amount of time it would take to example:
Complete a brute force word list.
I know how to use the time function and measure in time,
but the problem is i need to find out how long it would take in the program itself...
Here is the code i made this yesterday
import itertools, math
import os
Alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # Add or remove whatevs you think will be in the password you're cracking (example, [symbols])
counter = 1
CharLength = 1
range_num = int(raw_input("Enter range: "))
stopper = range_num + 1
filename = "bruteforce_%r.txt" % (range_num)
f = open(filename, 'a')
#n_1 = len(Alphabet)
#n_2 = n_1 - 1 # <-- total useless peice of garbage that could of been great in vurtual life
#n_3 = '0' * n_2
#n = '1' + n_3
x = range_num
y = len(Alphabet)
amount = math.pow(y, x)
total_items = math.pow(y, x)
for CharLength in range(range_num, stopper):
passwords = (itertools.product(Alphabet, repeat = CharLength))
for i in passwords:
counter += 1
percentage = (counter / total_items) * 100
amount -= 1
i = str(i)
i = i.replace("[", "")
i = i.replace("]", "")
i = i.replace("'", "")
i = i.replace(" ", "")
i = i.replace(",", "")
i = i.replace("(", "")
i = i.replace(")", "")
f.write(i)
f.write('\n')
print "Password: %r\tPercentage: %r/100\tAmount left: %r" % (i, int(percentage), amount)
if i == '0'* range_num:
print "*Done"
f.close()
exit(0)
else:
pass
This is my timer function i managed to make
#import winsound # Comment this out if your using linux
import os
import time
from sys import exit
print "This is the timer\nHit CTRL-C to stop the timer\nOtherwise just let it rip untill the time's up"
hours = int(raw_input('Enter the hours.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
minutes = int(raw_input('Enter the minutes.\n>>> '))
os.system('clear') # linux
#os.system('cls') # Windows
seconds = int(raw_input('Enter the seconds.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
stop_time = '%r:%r:%r' % (hours, minutes, seconds)
t_hours = 00
t_minutes = 00
t_seconds = 00
while t_seconds <= 60:
try:
os.system('clear') # Linux
#os.system('cls') # Windows
current_time = '%r:%r:%r' % (t_hours, t_minutes, t_seconds)
print current_time
time.sleep(1)
t_seconds+=1
if current_time == stop_time:
print "// Done"
#winsound.Beep(500,1000)
#winsound.Beep(400,1000)
break
elif t_seconds == 60:
t_minutes+=1
t_seconds=0
elif t_minutes == 60:
t_hours+=1
t_minutes = 00
except KeyboardInterrupt:
print "Stopped at: %r:%r:%r" % (t_hours, t_minutes, t_seconds)
raw_input("Hit enter to continue\nHit CTRL-C to end")
try:
pass
except KeyboardInterrupt:
exit(0)
Now i just cant figure out how to make this again but to calculate how long it will take rather than how long it is taking...
You cannot predict the time a script is going to take.
Firstly because two machines wouldn't run the script in the same time, and secondly, because the execution time on one machine can vary from on take to another.
What you can do, however, is compute the percentage of execution.
You need to figure out, for example, how many iterations your main loop will do, and calculate at each iteration the ratio current iteration count / total number of iterations.
Here is a minimalist example of what you can do:
n = 10000
for i in range(n):
print("Processing file {} ({}%)".format(i, 100*i//n))
process_file(i)
You can take it further and add the time as an additional info:
n = 10000
t0 = time.time()
for i in range(n):
t1 = time.time()
print("Processing file {} ({}%)".format(i, 100*i//n), end="")
process_file(i)
t2 = time.time()
print(" {}s (total: {}s)".format(t2-t1, t2-t0))
The output will look like this:
...
Processing file 2597 (25%) 0.2s (total: 519.4s)
Processing file 2598 (25%) 0.3s (total: 519.7s)
Processing file 2599 (25%) 0.1s (total: 519.8s)
Processing file 2600 (25%)
This is my implementation, which returns time elapsed, time left, and finish time in H:M:S format.
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
testimated = (telapsed/cur_iter)*(max_iter)
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated-telapsed # in seconds
return (int(telapsed), int(lefttime), finishtime)
Example:
import time
import datetime as dt
start = time.time()
cur_iter = 0
max_iter = 10
for i in range(max_iter):
time.sleep(5)
cur_iter += 1
prstime = calcProcessTime(start,cur_iter ,max_iter)
print("time elapsed: %s(s), time left: %s(s), estimated finish time: %s"%prstime)
Output:
time elapsed: 5(s), time left: 45(s), estimated finish time: 14:28:18
time elapsed: 10(s), time left: 40(s), estimated finish time: 14:28:18
time elapsed: 15(s), time left: 35(s), estimated finish time: 14:28:18
....
You will never ever be able to know exactly how long it is going to take to finish. The best you can do is calculate was percentage of the work you have finished and how long that has taken you and then project that out.
For example if you are doing some work on the range of numbers from 1 to 100 you could do something such as
start_time = get the current time
for i in range(1, 101):
# Do some work
current_time = get the current time
elapsed_time = current_time - start_time
time_left = 100 * elapsed_time / i - elapsed_time
print(time_left)
Please understand that the above is largely pseudo-code
The following function will calculate the remaining time:
last_times = []
def get_remaining_time(i, total, time):
last_times.append(time)
len_last_t = len(last_times)
if len_last_t > 5:
last_times.pop(0)
mean_t = sum(last_times) // len_last_t
remain_s_tot = mean_t * (total - i + 1)
remain_m = remain_s_tot // 60
remain_s = remain_s_tot % 60
return f"{remain_m}m{remain_s}s"
The parameters are:
i : The current iteration
total : the total number of iterations
time : the duration of the last iteration
It uses the average time taken by the last 5 iterations to calculate the remaining time. You can the use it in your code as follows:
last_t = 0
iterations = range(1,1000)
for i in iterations:
t = time.time()
# Do your task here
last_t = time.time() - t
get_remaining_time(i, len(iterations), last_t)

Python timestamp to time since conversion

I have a database column the holds timestamps in UNIX format, I am looking for a way to compare those timestamps to a timestamp from the time right now and print how many seconds/hours/days since the original timestamp.
Just to confirm I am NOT looking for a conversion from 1489757456 to 03/17/2017 # 1:30pm. I AM looking for a conversion from 1489757456 to 1m ago/2hr ago/3d ago ect.
datetime.datetime.fromtimestamp()
to convert your unix timestamp to a datetitme
datetime.datetime.now()
to get the current datetime
dateutil.relativedelta.relativedelta(dt1, dt2, ...)
to get the difference with respect to leap years.
References:
https://docs.python.org/3.6/library/datetime.html
http://dateutil.readthedocs.io/en/stable/relativedelta.html
Function, like this will generate output for hours, mins and seconds from seconds number.
def secondsToHms(d):
d = int(d);
h = math.floor(d / 3600)
m = math.floor(d % 3600 / 60)
s = math.floor(d % 3600 % 60)
htext = " hour, " if h == 1 else " hours, "
hDisplay = str(h) + htext if h > 0 else ""
mtext = " minute, " if m == 1 else " minutes, "
mDisplay = str(m) + mtext if m > 0 else ""
stext = " second" if s == 1 else " seconds"
sDisplay = str(s) + stext if s > 0 else ""
return hDisplay + mDisplay + sDisplay;
For example:
secondsToHms(344334)
>> 95.0 hours, 38.0 minutes, 54.0 seconds
So you can add your preferred formatting and also add days/months if needed in similar fashion.

Categories

Resources