如何计算工作时间内的总小时数?

2024-09-25 10:28:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我在pandas中有两列时间戳,分别是UTC:StartDateEndDate。日期是为请求帮助而提交的任务的日期。我试图计算这些任务在工作时间内完成前有多少小时。我公司营业时间为太平洋标准时间周一至周五上午8点至下午6点。你知道吗

我试图做这些计算,但遇到了一个问题。我不知道怎样才能在工作时间得到时间。我已经弄清楚了如何在整个时间段内计算时间,但我不知道如何向前推进。我现在的想法是在for循环中做一个if语句,并检查由我的计算生成的SLATable['Date Responded (Hours)']列的每个值,但上次我试图单独编辑value is in column时,python给了我一个错误。你知道吗

#8-6 PST to UTC time
officeOpen = pd.Timestamp("8:00:00.000").tz_localize('US/Pacific').tz_convert('utc')
officeClose = pd.Timestamp("18:00:00.000").tz_localize('US/Pacific').tz_convert('utc')

#get data from sql server
SLATable = pd.read_sql_query(SqlQuery,conn)

#calculate Date Responded
SLATable['Date Responded (Hours)'] = SLATable['EndDate'] - SLATable['StartDate']
SLATable['Date Responded (Hours)'] = round(SLATable['Date Responded (Hours)']/np.timedelta64(1,'h'), 2)

目前,如果我使用上面的代码,如果在工作时间创建的任务与创建的任务在同一天完成的任务都可以使用,但是星期一创建的任务和星期二完成的任务的工作时间将超出工作时间。另外,如果任务是在办公时间之外创建的,它将收集时间,直到我们在工作时间处理它。你知道吗

这些计算的目的并不是为了在任何国家的假日只周一至周五从8日至6日。你知道吗

在我的计算中运行的示例数据:

StartDate       EndDate       Date Responded (Hours)
2016-05-03      2016-05-03    0.13
15:51:11.850    15:59:13.017

2016-05-05      2016-05-06    17.64
23:01:51.023    16:40:21.350

如果计算正确,输出应该是什么:

StartDate       EndDate       Date Responded (Hours)
2016-05-03      2016-05-03    0.13
15:51:11.850    15:59:13.017

2016-05-05      2016-05-06    0.32
23:01:51.023    16:40:21.350

Tags: convertdate时间timestamptzpdusutc
1条回答
网友
1楼 · 发布于 2024-09-25 10:28:06

第一步是定义BusinessHour偏移量,并使用适当的 开始/结束时间(稍后使用):

bhOffs = pd.offsets.BusinessHour(start='08:00', end='18:00')

然后定义一个函数,用 正确的时区偏移:

def BusTime(ts, hOffs, fwd):
    '''Compute business time. Params:
    ts    - UTC time (string or Timestamp)
    hOffs - Hour offset (int)
    fwd   - Roll variant (forward / backward, bool)
    '''
    tsWrk = ts if type(ts) == 'str' else pd.Timestamp(ts)
    tsOffs = tsWrk + np.timedelta64(hOffs, 'h')
    if fwd:  # Roll if on End of Day
        tsRoll = bhOffs.rollforward(tsOffs + np.timedelta64(1, 'ms'))
    else:    # Don't roll if on End of Day
        tsRoll = bhOffs.rollforward(tsOffs - np.timedelta64(1, 'ms'))
    return tsRoll if tsRoll.day != tsOffs.day else tsOffs

最后一步,定义一个计算营业时间的函数:

def BusHrs(ts1, ts2, hOffs=0):
    '''Compute business hours between 2 DateTimes. Params:
    ts1, ts2 - From / To (UTC, Timestamp or string)
    hOffs    - Hour offset (int)
    '''
    t1 = BusTime(ts1, hOffs, True)
    t2 = BusTime(ts2, hOffs, False)
    bHrs = pd.date_range(start=t1.floor('h'), end=t2.floor('h'),
        freq=bhOffs, closed='left').size
    frac1 = t1 - t1.normalize() - np.timedelta64(t1.hour, 'h')
    frac2 = t2 - t2.normalize() - np.timedelta64(t2.hour, 'h')
    return bHrs + (frac2 - frac1) / np.timedelta64(1, 'h')

其目的是:

  • 将UTC开始/结束时间转换为正确的时区。你知道吗
  • 在本地开始/结束时间之间生成一个日期时间索引, 四舍五入到整小时。你知道吗
  • 从这个索引的大小中取完整的小时数。你知道吗
  • 从开始/结束时间开始,按小时的小数部分进行修正。你知道吗

我对你的数据进行了测试:

  • BusHrs('2016-05-03 15:51:11.850', '2016-05-03 15:59:13.017', -7)-结果 0.1336575。你知道吗
  • BusHrs('2016-05-05 23:01:51.023', '2016-05-06 16:40:21.350', -7)-结果 3.641757499998。你知道吗

第二个结果与您的预期结果不同,但基本原理 具体如下:

  • 开始时间:2016-05-05 23:01UTC是2016-05-05 16:01(太平洋地区)。你知道吗
  • 结束时间:2016-05-06 16:40UTC是2016-05-06 09:40(太平洋)。你知道吗
  • 2016-05-05的工作时间几乎是2小时(截至18:00)。你知道吗
  • 2016-05-06的工作时间几乎是1小时40分钟(从8:00开始)。你知道吗
  • 两个工作时间之和仅为3.64。。。。你知道吗

我没有在你的第三组开始/结束时间上测试这个函数 可能是出了问题(实际工作时间远远超过 你的预期结果)。你知道吗

相关问题 更多 >