'How to calculate hours between two differnet time in the 12 hour in python and also divide the hours into three parts (timesheet hours calculate)

Assume all times are between 6:00 PM and 6:00 AM. The input of time would be like

7:00    5:30     # 7:00 PM to 5:30 AM
6:00    1:45     # 6:00 PM to 1:45 AM

Divide the hours into three periods: the hours before 9:00 PM, hours between between 9:00 PM and midnight, and hours after midnight

My expected output

[2.0, 3.0, 5.5]
[3.0, 3.0, 1.75]

What I have:

import datetime as dt

start="9:00"
end="00:00"
start_dt = dt.datetime.strptime(start, '%H:%M')
end_dt = dt.datetime.strptime(end, '%H:%M')

hours_added = dt.datetime.strptime("12:00", '%H:%M')
diff = (end_dt - start_dt) 
if end < start:
    diff = diff.seconds/60/60 - 12.0
print(diff) # It prints 3.0

More other inputs

8:00   10:00
9:00    11:30
9:30    1:00
6:00    9:00
7:15    8:15
7:00    5:30
6:00    1:45
9:30    1:00
7:00    9:00
1:15    3:15
7:00    3:30
9:00    1:45


Solution 1:[1]

This was more challenging than it first appears - took me a while to figure out. The difficult part is dealing with the fact that the end time may be in the next day. I dealt with this by specifying the date in the datetime objects to make the datetime arithmetic simpler later on. I used 01/01/2020 for the first day and 02/01/2020 for the second day (dd/mm/YYYY format), but these could be any arbitrary dates.

I'm afraid I've run out of time to talk step-by-step through the code but hopefully it's descriptive enough to follow. Let me know if you have any questions!

import datetime as dt

start="06:00"
end="01:45"
# Parse the times so that you can get the hour and minute
start_dt = dt.datetime.strptime(start, '%H:%M')
end_dt = dt.datetime.strptime(end, '%H:%M')

# === CONVERT TO 24-HOUR CLOCK ===

# If the start time is later than 06:00, convert to PM.
if start_dt.hour < 6:
    start_dt = dt.datetime.strptime(f'02/01/2020 {start}AM', '%d/%m/%Y %I:%M%p')
else:
    start_dt = dt.datetime.strptime(f'01/01/2020 {start}PM', '%d/%m/%Y %I:%M%p')
# Do the same for end time (you could wrap this in a function later
# to avoid repetition)
if end_dt.hour < 6:
    end_dt = dt.datetime.strptime(f'02/01/2020 {end}AM', '%d/%m/%Y %I:%M%p')
else:
    end_dt = dt.datetime.strptime(f'01/01/2020 {end}PM', '%d/%m/%Y %I:%M%p')

# === DEFINE KEY TIME POINTS ===

nine_pm = dt.datetime.strptime(f'01/01/2020 09:00PM', '%d/%m/%Y %I:%M%p')
midnight = dt.datetime.strptime(f'02/01/2020 12:00AM', '%d/%m/%Y %I:%M%p')
zero_hours = dt.timedelta(hours=0)

# === DO THE MATH ===

total_hours = end_dt - start_dt

if total_hours > zero_hours:
    if end_dt > nine_pm:
        hours_before_nine = total_hours - (end_dt - nine_pm)
        total_hours = total_hours - hours_before_nine
    else:
        hours_before_nine = total_hours
        total_hours = zero_hours
else:
    hours_before_nine = zero_hours

if total_hours > zero_hours:
    if end_dt > midnight:
        hours_between_nine_and_midnight = total_hours - (end_dt - midnight)
        total_hours = total_hours - hours_between_nine_and_midnight
    else:
        hours_between_nine_and_midnight = total_hours
        total_hours = zero_hours
else:
    hours_between_nine_and_midnight = zero_hours

if total_hours > zero_hours:
    hours_after_midnight = total_hours
else:
    hours_after_midnight = zero_hours

# === PRINT THE RESULT ===

hours_before_nine = hours_before_nine.seconds/60/60
hours_between_nine_and_midnight = hours_between_nine_and_midnight.seconds/60/60
hours_after_midnight = hours_after_midnight.seconds/60/60

print([hours_before_nine, hours_between_nine_and_midnight, hours_after_midnight])

Solution 2:[2]

def calc_hours (time1,time2):
  import datetime as dt
  nl = []
  start= time1
  end= time2

  start_hour = int(start.split(":")[0])
  start_min = int(start.split(":")[1])

  end_hour = int(end.split(":")[0])
  end_min = int(end.split(":")[1])

  if end_hour < start_hour:
    end_hour += 12

  start_dt = dt.datetime.strptime(start, '%H:%M')
  end_dt = dt.datetime.strptime(end, '%H:%M')


  ninepm = dt.datetime.strptime("09:00",'%H:%M')
  midnight = dt.datetime.strptime("12:00",'%H:%M')
  hours_added = dt.datetime.strptime("12:00", '%H:%M')
  diff = (end_dt - start_dt)

  if start_hour + start_min/60 < 9:
    if end_hour <= 9:
      diff = diff.seconds/60/60
      nl.append(diff)
    elif end_hour <= 12:
      nl.append((ninepm - start_dt).seconds/60/60)
      if end_hour == 12:
        nl.append(((end_dt + dt.timedelta(hours=12))-ninepm).seconds/60/60)
      elif end_hour < 12:
        nl.append((end_dt-ninepm).seconds/60/60)
    elif end_hour > 12:
      nl.append((ninepm - start_dt).seconds/60/60)
      nl.append((midnight-ninepm).seconds/60/60)
      nl.append(((end_dt + dt.timedelta(hours=12))-midnight).seconds/60/60)

  elif start_hour + start_min/60 >= 9:
    if end_hour <= 12:
      if end_hour < 12:
        diff = diff.seconds/60/60
        nl.append(diff)
      elif end_hour == 12:
        nl.append(((end_dt + dt.timedelta(hours=12))-start_dt).seconds/60/60)
    else :
      nl.append((midnight-start_dt).seconds/60/60)
      nl.append(((end_dt + dt.timedelta(hours=12))-midnight).seconds/60/60)
      
  elif start_hour + start_min/60 > 12:
    nl.append(diff)
    
  return nl

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ljdyer
Solution 2 PyotrVanNostrand