Im using this code right now to get the difference of two different times
from time import strftime
from datetime import datetime
fmt = '%H:%M'
currentTimeString = strftime(fmt) #get the current time
gameTimeObject = datetime.strptime(time , fmt)
currentTimeObject = datetime.strptime(currentTimeString, fmt)
diff = currentTimeObject-gameTimeObject
diff_minutes = diff.seconds/60
I have a for loop that loops through different time values, 11:00, 12:00, 13:00, 14:00.
For the purpose of this example lets say the currentTime is 13:23
Im getting the result that i want when the time has passed meaning, 11:00, 12:00, 13:00 but when it comes to 14:00 the diff_minutes shows the value 1403
Why this is a problem is because I'm doing this after that code is executed
if diff_minutes >= 0 and diff_minutes <= 47:
time = str(diff_minutes)
elif diff_minutes >= 48 and diff_minutes <= 58:
time = "HT"
elif diff_minutes >= 59 and diff_minutes <= 103:
time = str(diff_minutes)
elif diff_minutes >= 104 and diff_minutes <= 107:
time = "90'"
elif diff_minutes >= 108: # HERE IS THE PROBLEM <<<<<<-------
time = "FT"
As you can see the times that has not yet been passed will change to "FT" since I'm using that if statement to know if the time of a games is over. How can i fix this?
--- EDIT more information of what I'm trying to do as asked
So what I'm trying to do here is to set the time variable to a soccer game. The different times as mentioned above 13:00 etc are the times of which when the game starts. So what i want to do is if the currentTime is 13:23, then i would change the time label of that soccer game to 23' since 23minutes has passed. If the total time that has passed is over 108 minutes then it means the game is over that is why i set the time variable to "FT" in the last if statement.
As i said before this is where the problem occurs since the diff_minutes gives me a value of higher than 108 minutes when the games has not yet been started it will change the time variable to "FT" which is wrong
So what we really should do is work only with datetime objects here. When you do math on them, the produce timedelta objects. These timedelta objects are comparable. This makes writing your code secretarial. Also - since an if/elif/else tree is short circuiting, you need not check if a time is between two times, just less than the upper bound. I admit my domain knowledge of soccer is limited to knowing it is a 90 minute game, so you may need to adjust this, but it should give you the idea.
import datetime
def gametime(hour, minute):
now = datetime.datetime.now()
starttime = datetime.datetime.combine(datetime.date.today(), datetime.time(hour, minute))
dif = now - starttime
if dif < datetime.timedelta(seconds=48*60):
return dif.seconds / 60
elif dif < datetime.timedelta(seconds=58*60):
return "Half Time"
elif dif < datetime.timedelta(seconds=104*60):
return dif.seconds / 60
elif dif < datetime.timedelta(seconds=108*60):
return "90'"
else:
return "Final"
PS: Seriously, Guido?
PPS: I should have tested this before posting it. I am sorry that I did not.
Related
This question already has answers here:
How to increase sleep/pause timing accuracy in python?
(4 answers)
Closed 5 months ago.
I've tried a few solutions from here with no luck. My Python timers are 10-30 seconds behind my smartphone stop watch after 10 minutes. I've tried the following:
def background3():
while True:
second = 0
minute = 0
hours = 0
while(True):
print('%d : %d : %d'%(hours,minute,second))
time.sleep(1)
second+=1
if(second == 60):
second = 0
minute+=1
if(minute == 60):
minute = 0
hour+=1;
and I also tried this:
def showCounter(self):
# Check the value of startWatch variable to start or stop the Stop Watch
if self.startWatch:
# Increment counter by 1
self.counter += 1
# Count and set the time counter value
cnt = int((self.counter/10 - int(self.counter/10))*10)
self.count = '0' + str(cnt)
# Set the second value
if int(self.counter/10) < 10 :
self.second = '0' + str(int(self.counter / 10))
else:
self.second = str(int(self.counter / 10))
# Set the minute value
if self.counter / 10 == 60.0 :
self.second == '00'
self.counter = 0
min = int(self.minute) + 1
if min < 10 :
self.minute = '0' + str(min)
else:
self.minute = str(min)
# Merge the mintue, second and count values
text = self.minute + ':' + self.second
# Display the stop watch values in the label
self.label.setText('<h1 style="color:white">' + text + '</h1>')
I'd like to be able to update a pyqt5 qlabel as time goes by every second, and I'd like to be able to display hours, minutes, and seconds in the qlabel. This has to be accurate as it is for work logging purposes. Eventually, I want to implement a qlabel that takes my overtime rate into consideration, and updates $ earned as time goes by. Does anybody have an example of what this may look like in pyqt5 using perhaps OS time ? Or is there some better way to do this?
EDIT:
This question is not a duplicate. The suggested articles were not helpful. I essentially need a way to count up from 0 using datetime. I tried replacing datetime.now but that did not work. The solutions suggested do not update my value in real time. They just take a stamp at the beginning, and subtract it from the end time. this is not what I am looking for. Does anybody know how I can watch seconds, minutes, and hours go by in real time through a pyqt5 qlabel?
def showCounter(self):
if self.startWatch:
text = str(datetime.now().strftime("%H:%M:%S"))
self.label.setText('<h1 style="color:white">' + str(text) + '</h1>')
Here's some code that prints every passing second without accumulating any lag. Just check the built-in clock at least once per second and update if the second has changed.
from datetime import datetime
import time
def time_to_str(time):
return str(time.hour) + ':' + str(time.minute) + ':' + str(time.second)
cur_time = datetime.now()
cur_str = time_to_str(cur_time)
while True:
time.sleep(0.2) # 200 ms, arbitrary
new_time = datetime.now()
new_str = time_to_str(new_time)
if new_str != cur_str:
print(new_str)
cur_str = new_str
The more often you check the time, the faster you can respond to the start of a new second. You'll never accrue lag regardless because you only print the time immediately after getting it from the system.
You should not expect a manufactured timer that relies on sleep() to be accurate for accrued time (stopwatch). Even if sleep() were 100% accurate, you are losing time outside of that in all of the function calls and other parts of the loop, which adds up over time (pun intended.)
The system time should be used. You can either use:
time.time()
or
datetime.now()
both have methods to peel out H:M:S.
As far as your "update loop"... well that is another story, you could use sleep there or whatever PyQt has to offer to refresh, but when you need to pull the time, do it as above.
If you want to use either as a "stopwatch" just capture the start time, do the subtraction. If you do this with datetime objects, the delta is a timedelta object that you can query. Do a little googling on timedelta and datetime.
Example:
In [1]: from datetime import datetime, timedelta
In [2]: tic = datetime.now()
In [3]: toc = datetime.now()
In [4]: td = toc - tic
In [5]: type(td)
Out[5]: datetime.timedelta
In [6]: td.seconds
Out[6]: 8
I have the following function (which comes from blinkstick library):
bstick.set_color(channel=0, index=0, name="red")
It basically switches on the first led (index=0) in a led strip connected via USB to my computer. index=1 would switch on the 2nd one and so on.
I would want the index parameter to store multiple values from 0 all the way up to 31 (since there are 32 leds in the strip).
I know that an easy and lazy workaround would be to just write the function 32 times and changing the index manually, but is there a smarter way to store 0-31 value inside this?
I tried:
while x < 32:
bstick.set_color(channel=0, index=x, name="white")
x+=1
but this is not really what I want since this is not very friendly with the way the rest of my project has been written so far, which is the following:
from datetime import datetime, time
import pandas
import ctypes
from playsound import playsound
from blinkstick import blinkstick
bstick = blinkstick.find_first()
def bstick_turn_on():
x=0
while x < 32:
bstick.set_color(channel=0, index=x, name="white")
x+=1
def bstick_turn_off():
x=0
while x < 32:
bstick.set_color(channel=0, index=x)
x+=1
file_path = "myfile.xlsx" #sunrise/sunset file path
data = pandas.read_excel(file_path, header=0) #Header on line 0
#Today as day number in reference to 1st of Jan
day = datetime.now().timetuple().tm_yday
#Today's parameters
#sr and ss are column names in the Excel spreadsheet for sunrise and sunset respectively
#Minus 1 to account for 0 based indexing
sunrise = data["sr"][day - 1]
sunset = data["ss"][day - 1]
#Time right now
now = datetime.now().time()
#Function to convert time objects into integers
def seconds_in_time(time_value: time):
return (time_value.hour * 60 + time_value.minute) * 60 + time_value.second
#Variable for a moment in time 5 minutes before the sunset
sunset_minus_five = seconds_in_time(sunset) - 60 * 5
#Setting up the day_night variable depending on the now variable
#delta calculates the difference in seconds between now and sunset -during night- and sunrise -during day-
#A negative value for delta means that now variable is equal to any moment between midnight and the sunrise
if now > sunrise and now < sunset:
day_night = 'day'
delta = (seconds_in_time(now) - seconds_in_time(sunrise))
else:
day_night = 'night'
delta = (seconds_in_time(now) - seconds_in_time(sunset))
#delta_notification calculates the difference in seconds between now and sunset_minus_five
delta_notification = seconds_in_time(now) - sunset_minus_five
#The path to the wallpapers being used
path = 'C:\\Users\\mariu\\Desktop\\Sunset\\wallpapers\\'+ day_night +'.jpg'
#Function defined to perform an action (open/close the light) depending on the time of the day
def on_off():
if now > sunrise and now < sunset:
return bstick_turn_on()
else:
return bstick_turn_off()
#Function to change the wallpaper
def changeBG(path):
ctypes.windll.user32.SystemParametersInfoW(20, 0, path, 3) #SystemParametersInfoW for x64 architecture
#An alarm sound is played and a red light turns on if delta_notification is less or equal than 15 seconds AND delta_notification is greater than -30 delta_notification <= 15 and delta_notification => -30:
if delta_notification <= 15 and delta_notification >= -30:
playsound('alarm.wav') #Plays the sound
bstick_turn_on()
#Wallpaper changes, a three-beep sound is played, and light turns on only if delta is less than 60 seconds AND delta is greater than -1
#In order for the light to turn on, the script should be ran on a computer that is on the same network as the light bulb (wireless)
if delta <= 15 and delta >= -30:
changeBG(path)
playsound('sound.mp3') #Plays the sound
on_off()
Since it appears all 32 lights are turned on or off together, I'd recommend making a function with parameters.
def set_light(color=None, count=32):
args = {'channel': 0}
if color is not None:
args['name'] = color
for x in range(count):
bstick.set_color(**args, index=x)
To turn things off, set_light(), to turn things on, set_light('white').
I'm suppose to write a code to give me the output of a value between 0 and 86400 and the current time in the 24 hour clock. However I am getting stuck when it comes to writing the formulas for the 24 hour clock and the print function. Here's the code I have written so far.
total_time = float('70000')
hours = int(total_time / 3600.0)
minutes = int((total_time - (hours * 3600.0)) / 60.0)
seconds = int(((total_time) - (hours * 3600) - (minutes * 60)))
print("Enter a value between 0 and 86400", total_time) print("The current time is",hours.minutes.seconds)
Firstly, get the current hour, minute and seconds:
import datetime
now = datetime.datetime.now()
# The current time:
hour = now.hour
minute = now.minute
second = now.second
Then simply output it:
print("Current time: {}:{}:{}".format(hour,minute,second))
It seems to me you are asking the user to enter a number between 0 and 86400 and then you want to translate that to hh:mm:ss format. But your code is not getting any input from the user, and the last line of the code has syntax errors.
To get you started, you need to fix your print() calls at the end. Put one statement to a line, and use commas not fullstops:
print("Enter a value between 0 and 86400", total_time)
print("The current time is",hours,minutes,seconds)
That will give you the output:
Enter a value between 0 and 86400 70000.0
The current time is 19 26 40
Which is correct, in the sense that an offset of 70,000 seconds from 0h00 today is 19h26m40s.
If you want to get actual user input, then you need to ask for it, at the top of your program, before you do the calculations, in an input() call:
total_time=float(input("Enter a value between 0 and 86400: "))
If you want pretty formatting of the answer then do
print(f"The current time is {hours:02d}:{minutes:02d}:{seconds:02d}")
None of this relates to finding the current time, which Suraj Kothari's answer addresses.
I am writing a python app where I only want processing to occur between a certain time range which is specified as parameters.
e.g. if the user provides parameters 9:00am 10:00pm, then the processing will only happen between that range.
The code below seems to achieve what I want however I am unsure how to handle the case where the start time is e.g. 11:00pm and end time is 08:00am. In this case 8am would refer to the next day however the code below wouldn't handle that.
Any advice?
Thanks
now = datetime.now()
now_time = now.time()
if now_time >= args.start and now_time <= args.end:
# Process as normal
else:
# Sleep until start time
dt_now = timedelta(hours=now_time.hour, minutes = now_time.minute, seconds=now_time.second, microseconds=now_time.microsecond)
dt_start = timedelta(hours=args.start.hour, minutes = args.start.minute, seconds=args.start.second, microseconds=args.start.microsecond)
time_to_wait = abs((dt_start - dt_now).seconds)
time.sleep(time_to_wait)
I am a beginner programmer in Python and I have no idea how to proceed with the following question. There are a ton of similar questions out there, however there are none having to do with Python code.
I have tried to compare the strings but I am uncertain how to make the comparison. I'm pretty sure I need to take the first two numbers (hours) and divide by 12 if it is greater than 12 ... but that presents problems.
Question:
Time Conversion (24hrs to 12hr)
Write a function that will allow the
user to convert the 24 hour time format to the 12 hour format (with
'am','pm' attached). Example: from '1400' to '2:00pm'. All strings
passed in as a parameter will have the length of 4 and will only
contain numbers.
Examples (tests/calls):
>>> convertTime('0000')
'12:00am'
>>> convertTime('1337')
'1:37pm'
>>> convertTime('0429')
'4:29am'
>>> convertTime('2359')
'11:59pm'
>>> convertTime('1111')
'11:11am'
Any input or different methods would be awesome!
You could use the datetime module, but then you would have to deal with dates as well (you can insert wathever you want there). Probably easier to simply parse it.
Update: As #JonClements pointed out in the comments to the original question, it can be done with a one liner:
from datetime import datetime
def convertTime(s):
print datetime.strptime(s, '%H%M').strftime('%I:%M%p').lower()
You can split the input string in the hours and minutes parts in the following way:
hours = input[0:2]
minutes = input[2:4]
And then parse the values to obtain an integer:
hours = int(hours)
minutes = int(minutes)
Or, to do it in a more pythonic way:
hours, minutes = int(input[0:2]), int(input[2:4])
Then you have to decide if the time is in the morning (hours between 0 and 11) or in the afternoon (hours between 12 and 23). Also remember to treat the special case for hours==0:
if hours > 12:
afternoon = True
hours -= 12
else:
afternoon = False
if hours == 0:
# Special case
hours = 12
Now you got everything you need and what's left is to format and print the result:
print '{hours}:{minutes:02d}{postfix}'.format(
hours=hours,
minutes=minutes,
postfix='pm' if afternoon else 'am'
)
Wrap it up in a function, take some shortcuts, and you're left with the following result:
def convertTime(input):
h, m = int(input[0:2]), int(input[2:4])
postfix = 'am'
if h > 12:
postfix = 'pm'
h -= 12
print '{}:{:02d}{}'.format(h or 12, m, postfix)
convertTime('0000')
convertTime('1337')
convertTime('0429')
convertTime('2359')
convertTime('1111')
Results in:
12:00am
1:37pm
4:29am
11:59pm
11:11am
Some tips
int("2300") returns an integer 2300
2300 is PM.
time >= 1200 is PM
time between 0000 and 1200 is AM.
You could make a function that takes a string, evaluates it as integer, then checks if it is greater or less than the above conditions and returns a print.
import datetime
hour = datetime.datetime.now().strftime("%H")
minute = datetime.datetime.now().strftime("%M")
if int(hour) > 12:
hour = int(hour) - 12
amPm = 'PM'
else:
amPm = 'AM'
if int(hour) == 12:
amPm = 'PM'
if int(hour) == 0:
hour = 12
amPm = 'AM'
strTime = str(hour) + ":" + minute + " " + amPm
print(strTime)
Take hour and minute from datetime. Convert hour to an int. Check if int(hour) > 12. If so, change from AM to PM. Assign hour with int(hour) - 12. Check if hour is 0 for 12 AM exception. Check if hour is 12 for 12 PM exception. Convert hour back into a string. Print time.