MATLAB的解决方案并不像大家想象的那么难看(尽管可以使用Financial Toolbox简化它)。简而言之,以下是接受两个^{}值的函数的解决方案:function workMins = work_time(startTime, endTime)
dateBlock = repmat((dateshift(startTime, 'start', 'day'):...
dateshift(endTime, 'start', 'day')).', 1, 2); %'
dateBlock(:, 1) = dateBlock(:, 1)+hours(8);
dateBlock(:, 2) = dateBlock(:, 2)+hours(17);
dateBlock(1, 1) = max(dateBlock(1, 1), startTime);
dateBlock(end, 2) = min(dateBlock(end, 2), endTime);
dateBlock((datestr(dateBlock(:, 1), 'd') == 'S'), :) = [];
workMins = minutes(sum(max(diff(dateBlock, 1, 2), 0)));
end
下面是它的工作原理。。。在
首先,我们将开始时间和结束时间作为datetime值:
^{pr2}$
现在我们可以创建日期时间的N-by-2矩阵。每一行都是一天,范围从startTime到endTime,现在时间设置为0:00:00:
^{3}$
现在我们将第一列时间设置为8:00:00,第二列时间设置为17:00:00:dateBlock(:, 1) = dateBlock(:, 1)+hours(8);
dateBlock(:, 2) = dateBlock(:, 2)+hours(17);
现在我们分别添加startTime和{}作为第一个和最后一个元素,将它们裁剪到8:00:00到{}时间范围内:dateBlock(1, 1) = max(dateBlock(1, 1), startTime);
dateBlock(end, 2) = min(dateBlock(end, 2), endTime);
接下来,我们删除^{}天值为'S'(即周末)的行:dateBlock((datestr(dateBlock(:, 1), 'd') == 'S'), :) = [];
最后,我们取列差,求和(忽略负值),然后转换为分钟:workMins = minutes(sum(max(diff(dateBlock, 1, 2), 0)));
我们得到了预期的结果:
^{8}$
编辑:
对于新请求,您可以稍微更改函数以允许传入一个工作日的开始和结束时间,如下所示:function workMins = work_time(startTime, endTime, workDayStart, workDayEnd)
dateBlock = repmat((dateshift(startTime, 'start', 'day'):...
dateshift(endTime, 'start', 'day')).', 1, 2); %'
dateBlock(:, 1) = dateBlock(:, 1)+hours(workDayStart);
dateBlock(:, 2) = dateBlock(:, 2)+hours(workDayEnd);
...
现在,您可以使用单独的工作时间范围调用它并添加结果:startTime = datetime('22/06/2017 18:00');
endTime = datetime('26/06/2017 09:00');
workTotal = work_time(startTime, endTime, 9.5, 11.5) ...
+ work_time(startTime, endTime, 13, 15);
或从较大范围中减去子范围:workTotal = work_time(startTime, endTime, 9.5, 15) ...
- work_time(startTime, endTime, 11.5, 13);
如果您希望将工作日时间指定为字符数组,可以这样编写函数:function workMins = work_time(startTime, endTime, workDayStart, workDayEnd)
dateBlock = repmat((dateshift(startTime, 'start', 'day'):...
dateshift(endTime, 'start', 'day')).', 1, 2); %'
workDayStart = datevec(workDayStart);
workDayEnd = datevec(workDayEnd);
dateBlock(:, 1) = dateBlock(:, 1)+duration(workDayStart(4:6));
dateBlock(:, 2) = dateBlock(:, 2)+duration(workDayEnd(4:6));
...
像这样使用它:workTotal = work_time(startTime, endTime, '9:30', '11:30') ...
+ work_time(startTime, endTime, '13:00', '15:00');