32

ユーザー入力からの合計日差をカウントしたい

たとえば、ユーザーが入力した場合

start_date = 2012-09-06end-date = 2012-09-11

今のところ、私はこのコードを使用して違いを見つけています

$count = abs(strtotime($start_date) - strtotime($end_date));
$day   = $count+86400;
$total = floor($day/(60*60*24));

合計の結果は6になります。しかし、問題は、週末(土曜日と日曜日)の日を含めたくないということです。

2012-09-06
2012-09-07
2012-09-08 Saturday
2012-09-09 Sunday
2012-09-10
2012-09-11

したがって、結果は4になります

- - アップデート - -

日付を含むテーブルがあります。テーブル名は休日の日付です

たとえば、テーブルには次のものが含まれます2012-09-07

したがって、休日の日付をカウントしなかったため、合計日は3日になります。

テーブルの入力から日付までの日付を等しくするにはどうすればよいですか?

4

12 に答える 12

56

私のお気に入りで非常に簡単です:DateTimeDateIntervalおよびDatePeriod

$start = new DateTime('2012-09-06');
$end = new DateTime('2012-09-11');
// otherwise the  end date is excluded (bug?)
$end->modify('+1 day');

$interval = $end->diff($start);

// total days
$days = $interval->days;

// create an iterateable period of date (P1D equates to 1 day)
$period = new DatePeriod($start, new DateInterval('P1D'), $end);

// best stored as array, so you can add more than one
$holidays = array('2012-09-07');

foreach($period as $dt) {
    $curr = $dt->format('D');

    // substract if Saturday or Sunday
    if ($curr == 'Sat' || $curr == 'Sun') {
        $days--;
    }

    // (optional) for the updated question
    elseif (in_array($dt->format('Y-m-d'), $holidays)) {
        $days--;
    }
}


echo $days; // 4
于 2012-09-11T08:26:35.030 に答える
11

私の場合、OP と同じ答えが必要でしたが、もう少し小さいものが欲しかったのです。@Bojanの答えは機能しましたが、オブジェクトでは機能せずDateTime、タイムスタンプを使用する必要がstringsあり、実際のオブジェクト自体の代わりに比較していたのが好きではありませんでした(ハッキーに感じます)...これが彼の答えの改訂版です。

function getWeekdayDifference(\DateTime $startDate, \DateTime $endDate)
{
    $days = 0;

    while($startDate->diff($endDate)->days > 0) {
        $days += $startDate->format('N') < 6 ? 1 : 0;
        $startDate = $startDate->add(new \DateInterval("P1D"));
    }

    return $days;
}

これに開始日と終了日を含めたい場合は、@xzdead のコメントに従ってください。

function getWeekdayDifference(\DateTime $startDate, \DateTime $endDate)
{
    $isWeekday = function (\DateTime $date) {
        return $date->format('N') < 6;
    };

    $days = $isWeekday($endDate) ? 1 : 0;

    while($startDate->diff($endDate)->days > 0) {
        $days += $isWeekday($startDate) ? 1 : 0;
        $startDate = $startDate->add(new \DateInterval("P1D"));
    }

    return $days;
}
于 2014-04-07T22:37:57.187 に答える
9

使用DateTime:

$datetime1 = new DateTime('2012-09-06');
$datetime2 = new DateTime('2012-09-11');
$interval = $datetime1->diff($datetime2);
$woweekends = 0;
for($i=0; $i<=$interval->d; $i++){
    $datetime1->modify('+1 day');
    $weekday = $datetime1->format('w');

    if($weekday !== "0" && $weekday !== "6"){ // 0 for Sunday and 6 for Saturday
        $woweekends++;  
    }

}

echo $woweekends." days without weekend";

// 4 days without weekends
于 2012-09-11T08:18:34.970 に答える
9

週末なしで違いを得る最も簡単で最速の方法は、Carbonライブラリを使用することです。

使用方法の例を次に示します。

<?php

$from = Carbon\Carbon::parse('2016-05-21 22:00:00');
$to = Carbon\Carbon::parse('2016-05-21 22:00:00');
echo $to->diffInWeekdays($from);
于 2016-12-14T17:04:48.013 に答える
7

date('N')は曜日を取得します(1-月曜日、7-日曜日)

$start = strtotime('2012-08-06');
$end = strtotime('2012-09-06');

$count = 0;

while(date('Y-m-d', $start) < date('Y-m-d', $end)){
  $count += date('N', $start) < 6 ? 1 : 0;
  $start = strtotime("+1 day", $start);
}

echo $count;
于 2012-09-11T08:33:06.463 に答える
3

@dan-lee 関数の改良版は次のとおりです。

function get_total_days($start, $end, $holidays = [], $weekends = ['Sat', 'Sun']){

    $start = new \DateTime($start);
    $end   = new \DateTime($end);
    $end->modify('+1 day');

    $total_days = $end->diff($start)->days;
    $period = new \DatePeriod($start, new \DateInterval('P1D'), $end);

    foreach($period as $dt) {
        if (in_array($dt->format('D'),  $weekends) || in_array($dt->format('Y-m-d'), $holidays)){
            $total_days--;
        }
    }
    return $total_days;
}

使用するには:

$start    = '2021-06-12';
$end      = '2021-06-17';
$holidays = ['2021-06-15'];
echo get_total_days($start, $end, $holidays); // Result: 3
于 2021-06-16T16:55:06.923 に答える
0

この投稿をご覧ください: 営業日を計算する

(あなたの場合、あなたは就業後/営業日のみであるため、「休日」の部分を省略することができます)

<?php
//The function returns the no. of business days between two dates
function getWorkingDays($startDate,$endDate){
    // do strtotime calculations just once
    $endDate = strtotime($endDate);
    $startDate = strtotime($startDate);


    //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24
    //We add one to inlude both dates in the interval.
    $days = ($endDate - $startDate) / 86400 + 1;

    $no_full_weeks = floor($days / 7);
    $no_remaining_days = fmod($days, 7);

    //It will return 1 if it's Monday,.. ,7 for Sunday
    $the_first_day_of_week = date("N", $startDate);
    $the_last_day_of_week = date("N", $endDate);

    //---->The two can be equal in leap years when february has 29 days, the equal sign is added here
    //In the first case the whole interval is within a week, in the second case the interval falls in two weeks.
    if ($the_first_day_of_week <= $the_last_day_of_week) {
        if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
        if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
    }
    else {
        // (edit by Tokes to fix an edge case where the start day was a Sunday
        // and the end day was NOT a Saturday)

        // the day of the week for start is later than the day of the week for end
        if ($the_first_day_of_week == 7) {
            // if the start date is a Sunday, then we definitely subtract 1 day
            $no_remaining_days--;

            if ($the_last_day_of_week == 6) {
                // if the end date is a Saturday, then we subtract another day
                $no_remaining_days--;
            }
        }
        else {
            // the start date was a Saturday (or earlier), and the end date was (Mon..Fri)
            // so we skip an entire weekend and subtract 2 days
            $no_remaining_days -= 2;
        }
    }

    //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder
//---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it
   $workingDays = $no_full_weeks * 5;
    if ($no_remaining_days > 0 )
    {
      $workingDays += $no_remaining_days;
    }    


    return $workingDays;
}

// This will return 4
echo getWorkingDays("2012-09-06","2012-09-11");
?>
于 2012-09-11T08:23:30.470 に答える
-1

http://pear.php.net/package/Date_Holidaysから Pear の Date_Holidays を使用して、2 つの日付間の営業日を計算し、米国の祝日を除外する別の方法を次に示します。

$start_date と $end_date は DateTime オブジェクトである必要があります (new DateTime('@'.$timestamp)タイムスタンプから DateTime オブジェクトへの変換に使用できます)。

<?php
function business_days($start_date, $end_date)
{
  require_once 'Date/Holidays.php';
  $dholidays = &Date_Holidays::factory('USA');
  $days = 0;

  $period = new DatePeriod($start_date, new DateInterval('P1D'), $end_date);

  foreach($period as $dt)
  {
    $curr = $dt->format('D');

    if($curr != 'Sat' && $curr != 'Sun' && !$dholidays->isHoliday($dt->format('Y-m-d')))
    {
      $days++;
    }
  }
  return $days;
}
?>
于 2013-10-05T12:59:30.857 に答える