drymoeuka282427675 2018-11-29 05:21
浏览 139

Php时间计算问题

<?php

function work_hours_diff($date1, $date2, $working_hours) {
    if ($date1 > $date2) {
        $tmp = $date1;
        $date1 = $date2;
        $date2 = $tmp;
        unset($tmp);
        $sign = -1;
    } else
        $sign = 1;
    if ($date1 == $date2)
        return 0;

    $days = 0;
    $working_days = array(1, 2, 3, 4, 5); // Monday-->Friday
    // $working_hours = array(8.5, 17.5); // from 8:30(am) to 17:30
    // $working_hours = array(8, 16); // from 8:30(am) to 17:30
    $current_date = $date1;
    $beg_h = floor($working_hours[0]);
    $beg_m = ($working_hours[0] * 60) % 60;
    $end_h = floor($working_hours[1]);
    $end_m = ($working_hours[1] * 60) % 60;

    // setup the very next first working timestamp

    if (!in_array(date('w', $current_date), $working_days)) {
        // the current day is not a working day
        // the current timestamp is set at the begining of the working day
        $current_date = mktime($beg_h, $beg_m, 0, date('n', $current_date), date('j', $current_date), date('Y', $current_date));
        // search for the next working day
        while (!in_array(date('w', $current_date), $working_days)) {
            $current_date += 24 * 3600; // next day
        }
    } else {
        // check if the current timestamp is inside working hours

        $date0 = mktime($beg_h, $beg_m, 0, date('n', $current_date), date('j', $current_date), date('Y', $current_date));
        // it's before working hours, let's update it
        if ($current_date < $date0)
            $current_date = $date0;

        $date3 = mktime($end_h, $end_m, 59, date('n', $current_date), date('j', $current_date), date('Y', $current_date));
        if ($date3 < $current_date) {
            // outch ! it's after working hours, let's find the next working day
            $current_date += 24 * 3600; // the day after
            // and set timestamp as the begining of the working day
            $current_date = mktime($beg_h, $beg_m, 0, date('n', $current_date), date('j', $current_date), date('Y', $current_date));
            while (!in_array(date('w', $current_date), $working_days)) {
                $current_date += 24 * 3600; // next day
            }
        }
    }

    // so, $current_date is now the first working timestamp available...
    // calculate the number of seconds from current timestamp to the end of the working day
    $date0 = mktime($end_h, $end_m, 59, date('n', $current_date), date('j', $current_date), date('Y', $current_date));
    $seconds = $date0 - $current_date + 1;

    printf("
From %s To %s : %d hours
", date('d/m/y H:i', $date1), date('d/m/y H:i', $date0), $seconds / 3600);

    // calculate the number of days from the current day to the end day

    $date3 = mktime($beg_h, $beg_m, 0, date('n', $date2), date('j', $date2), date('Y', $date2));
    while ($current_date < $date3) {
        $current_date += 24 * 3600; // next day
        if (in_array(date('w', $current_date), $working_days))
            $days++; // it's a working day
    }
    if ($days > 0)
        $days--; //because we've allready count the first day (in $seconds)

    printf("
From %s To %s : %d working days
", date('d/m/y H:i', $date1), date('d/m/y H:i', $date3), $days);

    // check if end's timestamp is inside working hours
    $date0 = mktime($beg_h, 0, 0, date('n', $date2), date('j', $date2), date('Y', $date2));
    if ($date2 < $date0) {
        // it's before, so nothing more !
    } else {
        // is it after ?
        $date3 = mktime($end_h, $end_m, 59, date('n', $date2), date('j', $date2), date('Y', $date2));
        if ($date2 > $date3)
            $date2 = $date3;
        // calculate the number of seconds from current timestamp to the final timestamp
        $tmp = $date2 - $date0 + 1;
        $seconds += $tmp;
        printf("
From %s To %s : %d hours
", date('d/m/y H:i', $date2), date('d/m/y H:i', $date3), $tmp / 3600) . "</br>";
    }

    // calculate the working days in seconds

    $seconds += 3600 * ($working_hours[1] - $working_hours[0]) * $days;

    printf("
From %s To %s : %d hours
", date('d/m/y H:i', $date1), date('d/m/y H:i', $date2), $seconds / 3600) . "</br>";
    $signHour = $sign * $seconds / 3600;
    $secondsValue = $seconds / 60;
    $showtotalHrMin = round($secondsValue);



    return $showtotalHrMin; // to get hours
}

//date_default_timezone_set('Asia/Calcutta'); 
$dt2 = strtotime("2018-11-26 9:00:00");
$dt1 = strtotime("2018-11-26 9:30:00");
$working_hours = array(8, 16);
echo work_hours_diff($dt1, $dt2, $working_hours);
?>

Same day this function is not working, rest of day working good. Removed Saturday, Sunday time and calculate only Monday to Friday 8:00 to 16:00 time duration.

I hold a report on 26 Nov at 9.00 then release this report on 26 Nov 9.30 According to my calculation 2018-11-26 9:00:00 to 2018-11-26 9:30:00 timeInterval is 0 hours 30 min only.

But calculation is wrong.

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥20 腾讯企业邮箱邮件可以恢复么
    • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
    • ¥15 错误 LNK2001 无法解析的外部符号
    • ¥50 安装pyaudiokits失败
    • ¥15 计组这些题应该咋做呀
    • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
    • ¥15 让node服务器有自动加载文件的功能
    • ¥15 jmeter脚本回放有的是对的有的是错的
    • ¥15 r语言蛋白组学相关问题
    • ¥15 Python时间序列如何拟合疏系数模型