首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要计算“移位窗口”(PHP)上的运行时间

需要计算“移位窗口”(PHP)上的运行时间
EN

Stack Overflow用户
提问于 2014-09-14 05:51:18
回答 1查看 110关注 0票数 0

我需要计算24小时和48小时内的多个睡眠事件。

时间计算本身并不是问题,问题是如何处理滚动周期。

我所说的“滚动期”是这样的:

轮班工人的睡眠以秒数和开始时间为单位进行记录。这很容易管理。

但是我需要捕获的是轮班工人在特定时间之前的24小时和48小时内的睡眠时间,例如下午4点。但是具体的时间是不同的。

因此,我们的轮班工人在9月1日从01:00到08:00睡觉,并有一天休息。她从9月1日22:00到9月2日06:00再次入睡,9月2日早上6:30开始工作。

我需要算法来计算她在早上6:30之前的24小时(即从9月1日6:30开始)和之前的48小时内睡了多少觉。

我甚至想不到如何简单地描述它,让我们来做一个算法。

我所能想到的就是拥有一个由48个元素组成的数组,每个元素代表一个小时,在记录睡眠时,用每小时睡眠的部分填充每个数组,然后每小时滚动数组。

卖给智囊团?

EN

回答 1

Stack Overflow用户

发布于 2014-09-14 10:01:22

在php中处理日期或时间计算的最简单的方法是使用DateTime objects。我必须对数据的格式做一些假设,但根据我的经验,这种设置是很常见的。

代码语言:javascript
复制
<?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;
?>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25828067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档