如何将unix时间戳上下舍入到最近的半小时?

时间:2012-03-09 19:09:21

标签: php datetime unix-timestamp

好的,所以我正在我的CRM系统中处理一个日历应用程序,我需要找到半小时的上限和下限超过某人在日历中输入事件的时间戳,以便运行一些SQL数据库,以确定他们是否已在该时间段内预订了某些内容。

例如我的时间戳为1330518155 = 2012年2月29日16:22:35 GMT + 4 所以我需要得到1330516800和1330518600等于16:00和16:30。

如果有人有任何想法或认为我正在以愚蠢的方式开发日历,请告诉我!这是我第一次参与这样一项涉及时间和日期工作的任务,所以任何建议都值得赞赏!

10 个答案:

答案 0 :(得分:64)

使用modulo。

$prev = 1330518155 - (1330518155 % 1800);
$next = $prev + 1800;

模运算符给出除法的余数部分。

答案 1 :(得分:3)

PHP确实有一个DateTime类和它提供的一整套方法。如果您愿意,可以使用这些,但我发现使用内置的date()strtotime()函数更容易。

这是我的解决方案:

// Assume $timestamp has the original timestamp, i.e. 2012-03-09 16:23:41

$day = date( 'Y-m-d', $timestamp ); // $day is now "2012-03-09"
$hour = (int)date( 'H', $timestamp ); // $hour is now (int)16
$minute = (int)date( 'i', $timestamp ); // $minute is now (int)23

if( $minute < 30 ){
  $windowStart = strtotime( "$day $hour:00:00" );
  $windowEnd   = strtotime( "$day $hour:30:00" );
} else {
  $windowStart = strtotime( "$day $hour:30:00" );
  if( ++$hour > 23 ){
    // if we crossed midnight, fix the date and set the hour to 00
    $day = date( 'Y-m-d', $timestamp + (24*60*60) );
    $hour = '00';
  }
  $windowEnd   = strtotime( "$day $hour:00:00" );
}

// Now $windowStart and $windowEnd are the unix timestamps of your endpoints

可以对此进行一些改进,但这是基本核心。

[编辑:更正了我的变量名称!]

[编辑:我已经重新回答了这个问题,因为在我的尴尬中,我意识到它没有正确处理一天中的最后半小时。我已经解决了这个问题。请注意$day是通过在时间戳中添加一天的秒来修复的 - 这样做意味着我们不必担心跨越月界,闰日等等因为无论如何,PHP都会为我们正确格式化。]

答案 2 :(得分:2)

您可以使用模运算符。

$time -= $time % 3600; // nearest hour (always rounds down)

希望这足以指出你正确的方向,如果不是,请添加评论,我会尝试制作一个更具体的例子。

答案 3 :(得分:2)

我没有清楚地阅读这些问题,但是对于那些不需要两者范围的人来说,这段代码将四舍五入到最近的半小时。使用一些SenorAmor的代码。道具和他对正确问题的疯狂优雅解决方案。

$time = 1330518155; //Or whatever your time is in unix timestamp

//Store how many seconds long our rounding interval is
//1800 equals one half hour
//Change this to whatever interval to round by
$INTERVAL_SECONDS = 1800;  //30*60

//Find how far off the prior interval we are
$offset = ($time % $INTERVAL_SECONDS); 

//Removing this offset takes us to the "round down" half hour
$rounded = $time - $offset; 

//Now add the full interval if we should have rounded up
if($offset > ($INTERVAL_SECONDS/2)){
  $nearestInterval = $rounded + $INTERVAL_SECONDS;
}
else{
  $nearestInterval = $rounded 
}

答案 4 :(得分:1)

如果您需要获取当前时间然后应用舍入(向下)时间,我会执行以下操作:

$now = date('U');
$offset = ($now % 1800);
$now = $now-$offset;
for ($i = 0;$i < 24; $i++)
{
    echo date('g:i',$now);
    $now += 1800;
}

或者你可以通过添加偏移来向上舍入,并做更多的事情而不仅仅是回应时间。然后for循环显示12小时的增量。我在最近的一个项目中使用了上述内容。

答案 5 :(得分:0)

您可能知道,UNIX时间戳是秒数,要减去/添加180030分钟内的秒数),您将获得所需的结果。

答案 6 :(得分:0)

我会使用localtimemktime功能。

$localtime = localtime($time, true);
$localtime['tm_sec'] = 0;
$localtime['tm_min'] = 30;
$time = mktime($localtime);

答案 7 :(得分:0)

远非我最好的工作......但是这里有一些使用字符串或unix时间戳的函数。

/**
 * Takes a timestamp like "2016-10-01 17:59:01" and returns "2016-10-01 18:00"
 * Note: assumes timestamp is in UTC
 * 
 * @param $timestampString - a valid string which will be converted to unix with time()
 * @param int $mins - interval to round to (ex: 15, 30, 60);
 * @param string $format - the format to return the timestamp default is Y-m-d H:i
 * @return bool|string
 */
function roundTimeString( $timestampString, $mins = 30, $format="Y-m-d H:i") {
    return gmdate( $format, roundTimeUnix( time($timestampString), $mins ));
}

/**
 * Rounds the time to the nearest minute interval, example: 15 would round times to 0, 15, 30,45
 * if $mins = 60, 1:00, 2:00
 * @param $unixTimestamp
 * @param int $mins
 * @return mixed
 */
function roundTimeUnix( $unixTimestamp, $mins = 30 ) {
    $roundSecs = $mins*60;
    $offset = $unixTimestamp % $roundSecs;
    $prev = $unixTimestamp - $offset;
    if( $offset > $roundSecs/2 ) {
        return $prev + $roundSecs;
    }
    return $prev;
}

答案 8 :(得分:0)

这是使用Asia/Kathmandu并保留时区信息等的解决方案。还将处理不是GMT偏移30分钟倍数的时区(例如/** * Return a DateTimeInterface object that is rounded down to the nearest half hour. * @param \DateTimeInterface $dateTime * @return \DateTimeInterface * @throws \UnexpectedValueException if the $dateTime object is an unknown type */ function roundToHalfHour(\DateTimeInterface $dateTime) { $hours = (int)$dateTime->format('H'); $minutes = $dateTime->format('i'); # Round down to the last half hour period $minutes = $minutes >= 30 ? 30 : 0; if ($dateTime instanceof \DateTimeImmutable) { return $dateTime->setTime($hours, $minutes); } elseif ($dateTime instanceof \DateTime) { // Don't change the object that was passed in, but return a new object $dateTime = clone $dateTime; $dateTime->setTime($hours, $minutes); return $dateTime; } throw new UnexpectedValueException('Unexpected DateTimeInterface object'); } )。

$dateTime = new DateTimeImmutable('@' . $timestamp)

您首先需要创建DateTime对象 - 可能需要{{1}}之类的东西。您还可以在构造函数中设置时区。

答案 9 :(得分:0)

对于那些可能需要在一天中的某些时候做的一些事情的人来说,这是一种更具语义的方法。

$time = strtotime(date('Y-m-d H:00:00'));

您可以将H更改为任何0-23的数字,因此可以四舍五入到当天的那个小时。