我有一个用PHP编写的接口,用于记录员工的工作时间。我想添加一个新算法来测量某些小时之间的工作时间,以便计算换档差异。我使用MySQL' unix_time()
作为时间戳。
示例:员工从下午6点到凌晨2点工作。在晚上10点到早上6点之间有一个付费班次差价。员工可获得4小时的正常工资和4小时的工资+差额。
$start_time = 1459015200; // 18:00 03/26/2016
$end_time = 1459044000; // 02:00 03/27/2016
$diff_start = mktime('22','00','00','3','26','2016');
$diff_end = mktime('06','00','00','3','27','2016');
我想编写一个脚本来计算晚上10点到下午6点之间的工作时间,考虑到工作时间的大量可能性。这个答案似乎完成了我正在寻找的东西,除了MySQL:Calculating time difference before 6am and after 10pm in MySQL
这个答案类似于我的问题:Calculate the number of hours in a given timeframe between two datetimes但是依赖于一个循环。鉴于基于unix_time
以秒为单位输入时间,我认为使用循环需要一秒钟的增量(这意味着每周有数千条记录通过循环)。
有没有一种有效的方法(例如MySQL示例)在PHP中执行此操作,并不需要按照第二个答案中的建议每增加一秒/分钟/小时进行循环?
答案 0 :(得分:1)
有:使用特殊形成的键的阵列。首先
mktime('22','00','00','3','26','2016') => 1459026000
mktime('06','00','00','3','27','2016') => 1459051200
现在构建差异数组:
$shifts=array (
0 => 0,
1459026000 => $diff,
1459051200 => 0
);
这意味着,从时间戳0..1459025999开始,差值为0,从1459026000到1459051199,差值为$diff
,从1459051200到无穷大,再次为0。当然,你真正的班次表会更大。
现在,您只需使用foreach ($shifts as $start=>$differential)
之类的内容运行此数组一次,并将$start
与$start_time
和$end_time
进行比较,以下是这些情况:
$start>$end_time
:忽略,这是将来的$start<$start_time
:忽略,这是过去的答案 1 :(得分:0)
喜欢这个问题。看起来像一个面试问题。我花了一些时间来有效地实现这一点,没有循环。首先,我实现了以下内容:
function date_intersection($a_from, $a_to, $b_from, $b_to);
在两个时间范围之间返回秒数。
然后,由于约束时班次不能超过24小时,我需要建立两个范围块:
之后,解决方案很简单:
$total = $end_time - $start_time;
$differ = date_intersection($b1s, $b1e, $start_time, $end_time) + date_intersection($b2s, $b2e, $start_time, $end_time);
$normal = $total-$differ;
有效地解决这个问题涉及不使用mktime()或date()来提取部分日期,因为你真的可以通过unix-timestamp解决模块运算符的问题。但是照顾DST真的让它很复杂。 如果你今晚没有问过这个问题,我会在之前(错误地)回答:)