我需要计算24小时和48小时的多个睡眠事件。
时间计算本身并不成问题,而是如何处理滚动期。
我的意思是滚动期'如下:
在开始时间过去的几秒钟内记录班次工作人员的睡眠。这很容易管理。
但我需要捕捉的是轮班工作人员在特定时间前24小时48小时内的睡眠时间,例如下午4点。但具体时间各不相同。
因此,我们的轮班工作人员将于9月1日01:00至08:00休息,并休息一天。 她于9月1日22:00至9月2日再次入睡,并于9月2日06:30开始工作。
我需要算法来计算她在早上6:30班次前24小时内(即自9月1日6:30开始)以及48小时之前的睡眠时间。
我甚至无法想到如何简单地描述,让我们做一个算法。
所有我能想到的就是拥有48个元素的数组,每个元素代表一个小时,并且在记录睡眠时,每个数组的每个小时都会睡眠,然后每小时滚动数组。 / p>
对大脑的信任?
答案 0 :(得分:0)
在php中处理日期或时间计算的最简单方法是使用DateTime objects。我将不得不对您的数据格式做出一些假设,但根据我的经验,这种设置很常见。
<?php
/** Your data */
$sleepCycles = array(
/** Dates as YYYY-MM-DD and times as HH:ii:ss */
array('sleepid'=>1,'startdate'=>'2014-01-01','starttime'=>'08:00:00','lengthinseconds'=>28800),
array('sleepid'=>2,'startdate'=>'2014-01-05','starttime'=>'17:00:00','lengthinseconds'=>28800)
);
/** The start and end of your rolling check period.
* $hoursToCheck and $start should be input.
* $start should be in format "YYYY-mm-dd HH:ii:ss"
*/
$rollStart = new DateTime( $start );
$rollEnd = new DateTime( $start );
/** $hoursToCheck should be a number or a string that resolves to a number. */
$rollEnd->modify('+'.$hoursToCheck.' hour');
/** The counter for how much sleep falls within your check */
$amountSleptInSeconds = 0;
foreach ( $sleepCycles as $sc )
{
$startDateObj = new DateTime( $sc['startdate'] .' '. $sc['starttime'] );
$endDateObj = new DateTime( $sc['startdate'] .' '. $sc['starttime'] );
$endDateObj->modify('+'.$sc['lengthinseconds'].' second');
/**
* If either the start or end of the sleep cycle fall
* inside the rolling check period,
* some part of the sleeping counts.
*/
if ( $rollStart <= $startDateObj && $startDateObj >= $rollEnd )
{
/** Get the time that counts. Note it may not be the entire sleep period.
* If both ends of the sleep also falls inside the check, count the entire
* length. If not, only count the sleep that is inside.
*/
if ( $endDateObj >= $rollEnd )
{ $amountSleptInSeconds += $sc['lengthinseconds']; }
else
{
$countMeInterval = $startDateObj->diff($rollEnd , TRUE);
$amountSleptInSeconds += $countMeInterval->format('%s');
}
}
else if ( $rollStart <= $endDateObj && $endDateObj >= $rollEnd )
{
if ( $rollStart <= $startDateObj )
{ $amountSleptInSeconds += $sc['lengthinseconds']; }
else
{
$countMeInterval = $rollEnd->diff($startDateObj , TRUE);
$amountSleptInSeconds += $countMeInterval->format('%s');
}
}
}
print 'Within time period '
.$rollStart->format('M j, Y g:ia').' - '
.$rollEnd->format('M j, Y g:ia')
.' (inclusive of end points) I found this amount of seconds of sleep: '
.$amountSleptInSeconds;
?>