Hi, I'm writing a program that totals how long someone has worked by the starting time and the ending time.

It DOES work if the times entered are both AM or PM. Like if they worked from 2:00 to 9:10, it tells me the right answer of 7 hours and 10 minutes. But if they work from 11:20 to 9:15 it tells me that they worked -2 hours and -5 minutes, and gives me the incorrect total at the end of the code after the hours have been entered for every day.

Here the code. I don't know how to go about adding AM and PM. I'm very new to Python (1 week) but I catch on fast.

Can anyone help?

from string import *
import os

print "When did they clock in Monday? Use HH:MM format."             
#Clock in time is what you type in. Entered as HH:MM.
clockinM = (raw_input())                                                

print "When did they clock out Monday?"
#Clock out time is what you type in.
clockoutM = (raw_input())                                               

#Splits the clock in time at the :
SsplitM = (split(clockinM,":"))                                         

#Splits the clock out time at the :
EsplitM = (split(clockoutM,":"))                                     

#The starting hours for Monday is part 0 of the split; the section in bracket. [HH]:MM
startHrsM = int(SsplitM[0])                                             
#The starting minutes for Monday is part 1 of the split; the section in brackets.HH:[MM]
startMinM = int(SsplitM[1])                                             

endHrsM = int(EsplitM[0])
endMinM = int(EsplitM[1])

#The total minutes worked on Monday is the ending minutes minus the starting minutes.
totalMinM = int(EsplitM[1])-int(SsplitM[1])                             
#The total hours worked on Monday is the ending hours minus the starting hours.
totalHrsM = int(EsplitM[0])-int(SsplitM[0]) 
                            
#Print the results
print "They worked",totalHrsM,"hours and",totalMinM,"minutes Monday."

Edited 6 Years Ago by WildBamaBoy: n/a

Look at vegaseat's code snippet about date and time handling and scroll down to the part that says "Calculate difference between two times (12 hour format) of a day:". That looks like what you need.

Nevermind what was here before. I figured out my stupid mistake.

It works now but gives me a stupid high number of minutes. I think I can figure this out...

Edited 6 Years Ago by WildBamaBoy: Figured it out

Alright here is the code now.

from string import *
import os
import sys
import time

def main():
    
    #-----------------------------------------------------------------------
    print "When did they clock in Monday? Format is HH:MMP"
    clockinM = raw_input()
    
    timeString1 = "05/23/10 " + clockinM
    timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")
    
    print "When did they clock out Monday?"
    clockoutM = raw_input()
    timeString2 = "05/23/10 " + clockoutM
    timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")
    
    totalTimeM = time.mktime(timeTuple2) - time.mktime(timeTuple1)
    print "They worked",totalTimeM/(60.0*60),"hours and",totalTimeM/60.0,"minutes on Monday."
    #----------------------------------------------------------------------

When I type in what is on the time card, 11:20AM to 9:15PM, I get this.

When did they clock in Monday? Format is HH:MMP
11:20AM
When did they clock out Monday?
9:10PM
They worked 9.83333333333 hours and 590.0 minutes on Monday.
When did they clock in Tuesday?

And I have this at the bottom to show me the total.

#------------------------------------------------------------------------
    totalTime = totalTimeM/(60.0*60) + totalTimeT/(60.0*60) + totalTimeW/(60.0*60) + totalTimeH/(60.0*60) + totalTimeF/(60.0*60) + totalTimeS/(60.0*60) + totalTimeU/(60.0*60)
    round(totalTime)
    print "They worked a total of",totalTime,"hours and",totalTime("%M"),"this week."
    
main()

When I start the program and get to the end (Entered the hours for every day) I get this error.

They worked a total of 52.75 hours and
Traceback (most recent call last):
    print "They worked a total of",totalTime,"hours and",totalTime("%M"),"this week."
TypeError: 'float' object is not callable
>>>

How can I get the hours and minutes to display correctly? It should tell me 9 hours and 55 minutes if I type 11:20AM and 9:15PM.

I got the hours to show correctly. Floor division! But the minutes are still messed up.
I don't understand why print totalTime("%M") doesn't work. Even if I change it to a string or integer it still says 'float' object is not callable.

totalTime is variable and it can not be called as function as it has not function value.

Thanks tonyjv, but I just can't figure this out. Using my incredible genius, (sarcasm) it finally clicked in my brain that the code in red cannot possibly give me how many minutes are left along with the hours. Because the code there now is meant to show me how many minutes are in the number of hours they worked! :$

It's supposed to show how many hours they worked, and then how many minutes are left.
Like, if the clock in time is 11:20AM, and clock out time is 9:15PM. The program should say that they worked 9 hours and 55 minutes that day.

import time

print "When did they clock in? Use HH:MMtt format."
clockIn = raw_input()

timeString1 = "05/23/10 " + clockIn
timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")

print "When did they clock out?"
clockOut = raw_input()

timeString2 = "05/23/10 " + clockOut
timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")

totalTime = time.mktime(timeTuple2) - time.mktime(timeTuple1)

print "They worked",totalTime//(60.0*60),"hours and",totalTime/60.0,"minutes today."

Here is what happens when I enter the clock in and clock out time I said above.

IDLE 2.6.5 ==== No Subprocess ====
>>>
When did they clock in? Use HH:MMtt format.
11:20AM
When did they clock out?
9:15PM
They worked 9.0 hours and 595.0 minutes today.
>>>

I don't know where to go from here to make this work...

Edited 6 Years Ago by WildBamaBoy: n/a

Sorry, I am lazy to reed your code so wrote this myself for your example strings:

start = '11:20AM'
finish = '9:15PM'

def hours(tim):
    if tim.endswith('AM'):
        st = tim.rstrip('AM').split(':')
        pm = 0
    elif tim.endswith('PM'):
        st = tim.rstrip('PM').split(':')
        pm = 12
    else: raise ValueError, 'Missing AM or PM'

    return (pm+int(st[0])+int(st[1])/60.0)

print 'Start',start,', finish',finish
print "Decimal hours: start %.1f, finish %.1f" % (hours(start),hours(finish))
print "%.1f hours" % (hours(finish)-hours(start))

Edited 6 Years Ago by pyTony: endswith instead of in

Thanks tonyjv, but I just can't figure this out. Using my incredible genius, (sarcasm) it finally clicked in my brain that the code in red cannot possibly give me how many minutes are left along with the hours. Because the code there now is meant to show me how many minutes are in the number of hours they worked! :$

It's supposed to show how many hours they worked, and then how many minutes are left.
Like, if the clock in time is 11:20AM, and clock out time is 9:15PM. The program should say that they worked 9 hours and 55 minutes that day.

import time

print "When did they clock in? Use HH:MMtt format."
clockIn = raw_input()

timeString1 = "05/23/10 " + clockIn
timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")

print "When did they clock out?"
clockOut = raw_input()

timeString2 = "05/23/10 " + clockOut
timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")

totalTime = time.mktime(timeTuple2) - time.mktime(timeTuple1)

print "They worked",totalTime//(60.0*60),"hours and",totalTime/60.0,"minutes today."

Here is what happens when I enter the clock in and clock out time I said above.

IDLE 2.6.5 ==== No Subprocess ====
>>>
When did they clock in? Use HH:MMtt format.
11:20AM
When did they clock out?
9:15PM
They worked 9.0 hours and 595.0 minutes today.
>>>

I don't know where to go from here to make this work...

Your code neglects to subtract the minutes that you have already converted into hours from the remaining minutes. For example, to convert 65 minutes into hours and minutes we need to divide 60 into 65 to get 1 hour with a remainder of 65 minus 60 minutes. I altered your code as follows:

import time
minutes_in_an_hour = 60.0
seconds_in_an_hour = minutes_in_an_hour * 60

print "When did they clock in? Use HH:MMtt format."
clockIn = raw_input()

timeString1 = "05/23/10 " + clockIn
timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")

print "When did they clock out?"
clockOut = raw_input()

timeString2 = "05/23/10 " + clockOut
timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")

totalTime = time.mktime(timeTuple2) - time.mktime(timeTuple1)

#The following line neglects to subtract time already converted to hours
#from the totalTime to calculate the remainder in minutes
#print "They worked",totalTime//(60.0*60),"hours and",totalTime/60.0,"minutes today."

#Do the following instead
print "They worked",int(totalTime//seconds_in_an_hour), \
      "hours and", \
      int(totalTime/minutes_in_an_hour - (totalTime//seconds_in_an_hour) * minutes_in_an_hour), \
      "minutes today."

Thank you, d5e5. That worked perfectly! Now I'm having problems when I need to skip a day. (The worker did not work that day.)

I tried to add the only kind of error checking I know and it does not work. The program will start but still gives me a ValueError if I leave the clock in time blank or type something random.

import time

mininhr = 60.0
secinhr = mininhr * 60
#-------------------------------------------------------------------------------
def Monday():
    valid = False
    while valid == False:
        try:            
            print "When did they clock in Monday? Use HH:MMtt format. Leave blank to skip."
            clockInM = raw_input()   #Monday's clock in time is what you type in.
            valid = True             #It is valid.
            if clockInM == None:     #If you didn't type anything,
                valid = True         #It is still valid. This skips the day and ends the loop.
                Tuesday()            #Goes to Tuesday
        except ValueError:           #You typed it incorrectly
            print "Incorrect format."#Tell them so and start over at try:
    
    timeString1 = "05/23/10 " + clockInM
    timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")

    print "When did they clock out Monday?"
    clockOutM = raw_input()

    timeString2 = "05/23/10 " + clockOutM
    timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")

    totalTimeM = time.mktime(timeTuple2) - time.mktime(timeTuple1)
#-------------------------------------------------------------------------------
def Tuesday():
    print "When did they clock in Tuesday? Use HH:MMtt format."
    clockInT = raw_input()

    timeString1 = "05/23/10 " + clockInT
    timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")

    print "When did they clock out Tuesday?"
    clockOutT = raw_input()

    timeString2 = "05/23/10 " + clockOutT
    timeTuple2 = time.strptime(timeString2, "%m/%d/%y %I:%M%p")

    totalTimeT = time.mktime(timeTuple2) - time.mktime(timeTuple1)
#-------------------------------------------------------------------------------

Skipping all of the days to the very bottom of the code where everything is summed up.

def Sum():
    sumTime = totalTimeM + totalTimeT + totalTimeW + totalTimeH + totalTimeF + totalTimeS + totalTimeU

    totalHours = sumTime//secinhr
    totalMins = sumTime//mininhr - sumTime//secinhr * mininhr

    print "They worked a total of",totalHours,"hours and",totalMins,"minutes this week."

Monday()

Here is the error.

IDLE 2.6.5 ==== No Subprocess ====
>>>
When did they clock in Monday? Use HH:MMtt format. Leave blank to skip.

Traceback (most recent call last):
File "C:\Documents and Settings\Dusty S. Alexander\My Documents\Programming\How Many Hours.py", line 128, in <module>
Monday()
File "C:\Documents and Settings\Dusty S. Alexander\My Documents\Programming\How Many Hours.py", line 20, in Monday
timeTuple1 = time.strptime(timeString1, "%m/%d/%y %I:%M%p")
File "C:\Python26\lib\_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "C:\Python26\lib\_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data '05/23/10 ' does not match format '%m/%d/%y %I:%M%p'
>>>

Something like this with strptime, even I think my own code for counting the difference was simpler:

import time

def timestr(t):
    """ verbalizes times to more understandable units.

        <-- takes time t as seconds,
        ---> returns string, which can be printed or added to other strings,

        modified to not return seconds, but minute accuracy
        timestr(mytime)[:-6], if time is known to be more than 1 second or adapt the function
        
        longest implemented unit days
    """
    if t>=24*60*60:
        days,t=divmod(t,24*60*60)
        return "%i days %s" % (days,timestr(t))        
    elif t>=60*60:
        hours,t=divmod(t,60*60)
        return "%i hours %s" % (hours,timestr(t))
    else: return "%i min" % (t//60) ## rounding to minute

def getampm(mess):
    clock = ' '
    while clock:
        try:            
            clock = raw_input(mess)
##            timeString1 =  clock
            return time.strptime( "05/23/10 " +clock, "%m/%d/%y %I:%M%p")
        except ValueError:                       #You typed it incorrectly
            if clock: print "Incorrect format."  #Tell them so and start over at try:
    return 0

def day(wd):
    timeTuple1 = getampm("When did they clock in %s? " % wd)
    if timeTuple1:
        timeTuple2 = getampm("When did they clock out %s? " % wd)
        if timeTuple2:
            return time.mktime(timeTuple2) - time.mktime(timeTuple1)
    print wd, 'skipped'
    return 0


tottime = 0    
for weekday in ['Monday','Tuesday','Wednesday','Thursday','Friday']:
    seconds=day(weekday)
    print weekday,':',timestr(seconds)
    tottime += seconds

print 'Total hours are',timestr(tottime)

Edited 6 Years Ago by pyTony: Added my timestr addapted to minutes

Comments
Nicely done.

The ValueError occurs after your while valid == False: loop has completed. Since the ValueError occurs outside the loop where you do your exception handling, it is not handled and so crashes the program.

Sorry, tonyjv, I posted the above before noticing your solution, and it was too late to edit or delete mine. I agree it is much better to call the same function for each weekday than to define separate functions for Monday, Tuesday, etc.

This question has already been answered. Start a new discussion instead.