计算两次之间经过的部分时间

时间:2016-03-26 23:28:46

标签: php

我有一个用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中执行此操作,并不需要按照第二个答案中的建议每增加一秒/分钟/小时进行循环?

2 个答案:

答案 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:忽略,这是过去的
  • else:计算秒数并使用$ differential

答案 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真的让它很复杂。 如果你今晚没有问过这个问题,我会在之前(错误地)回答:)