Home > Blockchain >  Calculation of business working hour in python
Calculation of business working hour in python

Time:09-12

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])

CodePudding user response:

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

  • Related