python计算请假时间或有效工作时间

最近在研究bpm系统,稍微整理一下请假表单的请假时间计算
这里只考虑了一天一个中休,且正常工作时间8小时,一周放两天
如果有法定节假日需要计算的话,需要用接口先获取法定节假日的数据,或者是先存一份节假日数据用于读取

整体思路
1.如果是同一天的话,考虑各种情况计算时间间隔
2.如果不是同一天的话,把时间分为三个部分
请假第一天/中间间隔天数/请假最后一天
3.用计算同一天有效时间的方式把第一天和最后一天算出来
4.加上中间间隔的完整的工作日时间

import datetime
import time
from datetime import timedelta
from dateutil import rrule


# 向上整点
def toptime(date):
    return datetime.datetime.strptime(date.strftime('%Y-%m-%d')+' 00:00:00', '%Y-%m-%d %H:%M:%S')
# 向下整点
def uptime(date):
    return datetime.datetime.strptime(date.strftime('%Y-%m-%d')+' 00:00:00', '%Y-%m-%d %H:%M:%S')+timedelta(days=1)


# 一天时间
def oneday_worktime(start_date,end_date,begin,rest,restend,end):
    #开始时间和结束时间当天小时换算
    opens = start_date.hour+(start_date.minute/60)
    closes =  end_date.hour+(end_date.minute/60)
    if end_date>=start_date:
        if closes==0:
            closes = 24
    #初始默认值为0
    gap = 0
    # 如果计算时间在非周末
    if start_date.isoweekday() in [1,2,3,4,5]:
        #如果在小于等于开始上班时间
        if opens<=begin:
            # 如果在中休前结束假期
            if closes<=rest:
                gap = closes-begin #直接减出来-----------------------------------------------------------------------------------------
            #如果在晚上下班前结束
            elif closes<=end:
                gap = closes-begin-(restend-rest) #多减去一个中休-----------------------------------------------------------------------
            # 如果在晚上下班后结束
            else:
                gap = rest-begin + end - restend  #同一天又超过当天下班时间则为一整天工时-------------------------------------------------
        #如果在上午中途请假
        elif opens<=rest:
            # 如果在中休前结束
            if closes<=rest:
                gap = closes-opens #直接减出来-----------------------------------------------------------------------------------------
            # 如果在晚上下班前结束
            elif closes<=end:
                gap = closes-opens-(restend-rest) #多减去一个中休-----------------------------------------------------------------------
            # 如果在晚上下班后结束
            else:
                gap = end-opens - (restend-rest) #------------------------------------------------------------------------------------------
        #如果在中休结束之前请假
        elif opens<=restend:
            #如果下午提前回来
            if closes<=end:
                gap = closes-restend
            else:
                gap = end - restend
        #如果在晚上下班前请假
        elif opens<=end:
            #如果下午提前回来
            if closes<=end:
                gap = closes-opens
            else:
                gap = end - opens
        #如果乱选在晚上之后请假
        else:
            gap = 0
    #如果不在工作日
    else:
        gap = 0
    #如果前后时间相等,则扣掉默认赋予的24小时计算出来的时间
    if end_date==start_date:
        gap =0       
    return gap

def work_day(start_date,end_date):
    days_off = 5, 6
    workdays = [x for x in range(7) if x not in days_off]    
    secondly = rrule.rrule(rrule.DAILY, dtstart=start_date, until=end_date, byweekday=workdays)
    seconds = secondly.count()
    return seconds-1


# gap = 0
# start_date = datetime.datetime.strptime('2020-09-02 13:21:46', '%Y-%m-%d %H:%M:%S')
# end_date = datetime.datetime.strptime('2020-09-09 17:21:46', '%Y-%m-%d %H:%M:%S')
# begin =8.0
# rest =12
# restend =13.5
# end =17.5

def gap_time(start_date,end_date,begin=8.0,rest=12.0,restend=13.5,end=17.5):
    #如果开始和结束都在同一天
    if start_date.year==end_date.year and start_date.month==end_date.month and start_date.day==end_date.day:
        gap = oneday_worktime(start_date,end_date,begin,rest,restend,end)
    #如果不在同一天
    else:
        # 获取开始时间的下整点
        first = uptime(start_date)
        # 获取介素时间的上整点
        last = toptime(end_date)
        #计算第一天的时间
        gap1 = oneday_worktime(start_date,first,begin,rest,restend,end)
        #计算最后一天的时间
        gap2 = oneday_worktime(last,end_date,begin,rest,restend,end)
        #计算第一天之后,最后一天之前的天数
        daynum = work_day(first,last)
        gap3 = daynum*(rest-begin+end-restend)
        gap = gap1+gap2+gap3
    return gap

# print(gap_time(start_date,end_date))
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

isSamle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值