计算两个日期之间的夜间时间

时间:2019-10-14 08:35:16

标签: php

我想计算两个给定日期之间的夜间(21PM到6AM)。

我没有任何想法

public function biss_hours($start, $end){
    $startDate = new \DateTime($start);
    $endDate = new \DateTime($end);
    $periodInterval = new \DateInterval( "PT1H" );

    $period = new \DatePeriod( $startDate, $periodInterval, $endDate );
    $count = 0;

    foreach($period as $date){

        $startofday = clone $date;
        $startofday->setTime(5,59);

        $endofday = clone $date;
        $endofday->setTime(20,59);

        if($date > $startofday && $date < $endofday){
            $count++;
        }

    }
    return $count;
}

我有此功能,但不起作用:)

需要任何帮助

1 个答案:

答案 0 :(得分:0)

没有必要在一段时间内循环播放。正如评论中已经建议的那样,首先要计算开始日期和结束日期的小时数,因为这些时间实际上可能少于一整夜。计算完这些后,您只需获取剩余天数,然后乘以一个晚上的小时数即可。

请注意,在下面的示例中,我仅考虑小时数,因此22:55到24:00将计算2整个小时的夜间时间。此外,它也不检查结束日期早于开始日期或输入是否有效的情况。它应该可以将想法传达出来:

function getHoursForSingleDay ( $startTime, $endTime, $nightStart, $nightEnd ) {
    $numHours = 0;

    // if the day starts before night ends
    if( $startTime < $nightEnd ) {
        // e.g. Night ends at 6a.m. - day starts at 5 a.m. = 1 hour
        $numHours += $nightEnd - $startTime;
    }

    // if the day ends after night starts
    if( $endTime > $nightStart ) {
        // e.g. day ends at 23 - night starts at 21 = 2 hours
        $numHours += $endTime - $nightStart;
    }

    return $numHours;
}

function biss_hours ( $start, $end, $nightStart = 21, $nightEnd = 6 ) {
    $startDate = new \DateTime( $start );
    $endDate   = new \DateTime( $end );

    $startTime = intval( $startDate->format( 'H' ) );
    $endTime   = intval( $endDate->format( 'H' ) );

    // Both dates being the same day is an edge case
    if( $startDate->format( 'Y-m-d' ) === $endDate->format( 'Y-m-d' ) ) {
        return getHoursForSingleDay( $startTime, $endTime, $nightStart, $nightEnd );
    }

    // get the hours for bot the start and end date, since they can be less than a full night
    $numHours = getHoursForSingleDay( $startTime, 24, $nightStart, $nightEnd );
    $numHours += getHoursForSingleDay( 0, $endTime, $nightStart, $nightEnd );

    // all remaining days in between can be calculated in a rather simple way
    $nightHoursPerDay = $nightEnd + ( 24 - $nightStart );
    // -1 because diff returns 1 for two adjacent days, but we treat the first and last day specially
    $numDaysBetween = intval( $endDate->diff( $startDate )->format( "%a" ) ) - 1;
    $numHours       += $numDaysBetween * $nightHoursPerDay;

    return $numHours;
}