php 没有周末的日差

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12365461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 03:25:38  来源:igfitidea点击:

Day difference without weekends

phpcodeigniterdate

提问by Belajar

I want to count the total day difference from user input

我想计算用户输入的总天差

For example when the user inputs

例如当用户输入

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

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

For now I am using this code to find the diffeence

现在我正在使用此代码来查找差异

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

The result of total will be 6. But the problem is that I dont want to include the days at weekend (Saturday and Sunday)

total 的结果将是 6。但问题是我不想包括周末(周六和周日)的天数

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

So the result will be 4

所以结果将是 4

----update---

- - 更新 - -

I have a table that contains date,the table name is holiday date

我有一个包含日期的表,表名是假期日期

for example the table contains 2012-09-07

例如该表包含 2012-09-07

So, the total day will be 3, because it didn't count the holiday date

所以,总天数将是 3,因为它没有计算假期日期

how do I do that to equate the date from input to date in table?

我如何做到这一点以将日期从输入到表中的日期等同起来?

回答by dan-lee

Very easy with my favourites: DateTime, DateIntervaland DatePeriod

我最喜欢的很容易:DateTimeDateIntervalDatePeriod

$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

回答by Lander

In my case I needed the same answer as OP, but wanted something a little smaller. @Bojan's answer worked, but I didn't like that it doesn't work with DateTimeobjects, required using timestamps, and was comparing against stringsinstead of the actual objects themselves (which feels hacky)... Here's a revised version of his answer.

在我的情况下,我需要与 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;
}

Per @xzdead's comment if you'd like this to be inclusive of the start andend date:

如果您希望包含开始结束日期,请根据 @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;
}

回答by Mihai Iorga

use DateTime:

使用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

回答by huan

The easiest and fastest way to get difference without weekends is by using Carbonlibrary.

在没有周末的情况下获得差异的最简单和最快的方法是使用Carbon库。

Here's an example how to use it:

这是一个如何使用它的示例:

<?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);

回答by Bojan Devi?

date('N') gets the day of the week (1 - Monday, 7 - Sunday)

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;

回答by Terry Seidler

Have a look at this post: Calculate business days

看看这篇文章: 计算工作日

(In your case, you could leave out the 'holidays' part since you're after working/business days only)

(在您的情况下,您可以省略“假期”部分,因为您只在工作日/工作日之后)

<?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");
?>

回答by SubaRajasekaran

/**
 * Getting the Weekdays count[ Excludes : Weekends]
 * 
 * @param type $fromDateTimestamp
 * @param type $toDateTimestamp
 * @return int
 */
public static function getWeekDaysCount($fromDateTimestamp = null, $toDateTimestamp=null) {

    $startDateString   = date('Y-m-d', $fromDateTimestamp);
    $timestampTomorrow = strtotime('+1 day', $toDateTimestamp);
    $endDateString     = date("Y-m-d", $timestampTomorrow);
    $objStartDate      = new \DateTime($startDateString);    //intialize start date
    $objEndDate        = new \DateTime($endDateString);    //initialize end date
    $interval          = new \DateInterval('P1D');    // set the interval as 1 day
    $dateRange         = new \DatePeriod($objStartDate, $interval, $objEndDate);

    $count = 0;

    foreach ($dateRange as $eachDate) {
        if (    $eachDate->format("w") != 6 
            &&  $eachDate->format("w") != 0 
        ) {
            ++$count;
        }
    }
    return $count;
}

回答by Kiryamwibo Yenusu

Kindly have a look at this precise php function returning days count with weekends excluded.

请看看这个精确的 php 函数返回天数,周末除外。

function Count_Days_Without_Weekends($start, $end){
    $days_diff = floor(((abs(strtotime($end) - strtotime($start))) / (60*60*24)));
    $run_days=0;
    for($i=0; $i<=$days_diff; $i++){
        $newdays = $i-$days_diff;
        $futuredate = strtotime("$newdays days");
        $mydate = date("F d, Y", $futuredate);
        $today = date("D", strtotime($mydate));             
        if(($today != "Sat") && ($today != "Sun")){
            $run_days++;
        }
    }
return $run_days;
}

Try it out, it really works..

试试看,确实有效。。

回答by user1518458

If you don't need full days but accurate seconds instead try this code. This accepts unix timestamps as an input.

如果您不需要全天但需要准确的秒数,请尝试使用此代码。这接受 unix 时间戳作为输入。

function timeDifferenceWithoutWeekends($from, $to) {
    $start = new DateTime("@".$from);
    $current = clone $start;
    $end = new DateTime("@".$to);
    $sum = 0;
    while ($current<$end) {
        $endSlice = clone $current;
        $endSlice->setTime(0,0,0);
        $endSlice->modify('+1 day');
        if ($endSlice>$end) {
            $endSlice= clone $end;
        }
        $seconds = $endSlice->getTimestamp()-$current->getTimestamp();
        $currentDay = $current->format("D");
        if ($currentDay != 'Sat' && $currentDay != 'Sun') {
            $sum+=$seconds;
        }
        $current = $endSlice;
    }
    return $sum;
}

回答by Weboide

Here's an alternative to calculate business days between two dates and also excludes USA holidays using Pear's Date_Holidays from http://pear.php.net/package/Date_Holidays.

这是计算两个日期之间的工作日的替代方法,并且还使用来自http://pear.php.net/package/Date_Holidays 的Pear 的 Date_Holidays 排除美国假期。

$start_date and $end_date should be DateTime objects (you can use new DateTime('@'.$timestamp)to convert from timestamp to DateTime object).

$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;
}
?>