使用数组对TimeSheet进行排序

时间:2016-04-25 21:39:58

标签: php datetime time

使用PHP 5.4.45

我一直在制作一个非常简单的时间表,允许用户输入和输出时钟,查看他们的工作时间等。到目前为止,一切都很顺利,但是,我似乎无法找出按工作周分割工作日的方法。现在,它将显示您每天工作的每个小时。我的想法是创建一个父键Key =>值数组到上周一(或周开始)作为排序方法。

 CREATE TABLE `#__handiclock` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `userId` int(10) NOT NULL,
   `location` varchar(255) DEFAULT '0.0.0.0',
   `timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
   `modId` int(10),
   `modified` TIMESTAMP,
   `state` tinyint(4) NOT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

使用当前代码,每个时钟输入和输出都分别存储在数据库中。状态1是时钟输入,0是时钟输出。这为将来可能的状态留下了充足的空间。或者"带薪假期"默认情况下,系统将使用TIMESTAMP,但管理员可以通过设置MODIFIED来改变小时数,以便原始时间永远不会改变。

function parseTimesheet($info) {
    $timesheet = new TimeSheet;
    $timesheet->User = JFactory::getUser()->name;
    $timesheet->Clocks = array();
    $in = 0; $out = 0;
    $clock = new Clock;
    $clock->Time = strtotime('0000-00-00 00:00:00');
    $clock->Breaks = 0;
    $clock->Hours = 0;
    $day = "01/01/1970";
    foreach ($info as $i => $row) {
        if ($row->state == 1) {
            // Clock IN
            $day = date("m/d/Y", strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp));
            $in = strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp);
            if (array_key_exists($day, $timesheet->Clocks)) {
                $clock = $timesheet->Clocks[$day];
                $clock->Breaks += ($in - $out);
            } else {
                $timesheet->Clocks[$day] = new Clock();
                $clock = $timesheet->Clocks[$day];
            }
            $clock->Time = date("g:i A", strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp));
        } else {
            // Clock OUT
            $newday = date("m/d/Y", strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp));
            if ($day != $newday) {
                // crossed midnight, split accordingly
                $mndate = new DateTime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp);
                $mndate->setTime(12,0,0);
                $midnight = $mndate->getTimestamp();
                $clock->Hours += ($midnight - $in);
                $timesheet->Clocks[$day] = $clock;

                $_clock = new Clock; // tomorrows time
                $in = $midnight;
                $out = strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp);
                $_clock->Hours = ($out - $in);
                $timesheet->Clocks[$newday] = $_clock;
                $clock = $timesheet->Clocks[$newday];
            } else {
                $out = strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp);
                $clock->Hours += ($out - $in);
                $timesheet->Clocks[$day] = $clock;
            }
        }
    }
    //echo '<br>Parsing Complete!';
    return $timesheet;
}

代码基本上每天分开,并占午夜交叉。它会自动计算休息时间,但会有午夜交叉的故障。并不重要,因为这更像是管理员深入研究的估计因素。

实际问题是试图找出一个数学函数,它会为一周中的所有日子创建一个相同的KEY,但每周都是唯一的。

1 个答案:

答案 0 :(得分:1)

我希望能帮助您解决以下代码问题。我重构了代码并更改了变量的名称以便于阅读,但代码的结构或多或少相同。

function parseTimesheet($info) {
    $timesheet = new TimeSheet;
    $timesheet->User = JFactory::getUser()->name;
    $timesheet->Clocks = array();

    $in_timestamp = 0;
    $out_timestamp = 0;
    $in_key = NULL;
    $out_key = NULL;
    foreach ($info as $row) {
        $row_timestamp = strtotime(($row->modified != '0000-00-00 00:00:00') ? $row->modified : $row->timestamp);

        if ($row->state == 1) {
            // Clock IN
            $in_timestamp = $row_timestamp;
            $in_key = date('Y-W', $in_timestamp);

            if (isset($timesheet->Clocks[$in_key])) {
                $timesheet->Clocks[$in_key]->Breaks += ($in_timestamp - $out_timestamp);
            } else {
                $timesheet->Clocks[$in_key] = new Clock();
            }
            // I don't understand what it does, but I have copyed it from the above code
            $timesheet->Clocks[$in_key]->Time = date("g:i A", $row_timestamp);
        } else {
            // Clock OUT
            $out_timestamp = $row_timestamp;
            $out_key = date('Y-W', $out_timestamp);

            // in this way I handle also if someone work for two weeks without break...
            while ($in_key != $out_key) {
                // the way used to compute $border_timestamp depends on the interval delay chosen

                // compute the timestamp of the first day of the week after 
                // note: strtotime('2016W02') returns the timestamp of the monday of the second week of the 2016
                $border_timestamp = strtotime(date('Y\WW', $in_timestamp + 3600*24*7));
                $border_key = date('Y-W', $border_timestamp);

                $timesheet->Clocks[$in_key]->Hours += ($border_timestamp - $in_timestamp);
                $timesheet->Clocks[$border_key] = new Clock();

                // virtually update the IN clock
                $in_timestamp = $border_timestamp;
                $in_key = $border_key;
            }
            $timesheet->Clocks[$in_key]->Hours += ($out_timestamp - $in_timestamp);
        }
    }
    //echo '<br>Parsing Complete!';
    return $timesheet;
}