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
Day difference without weekends
提问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-06和 end-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
我最喜欢的很容易:DateTime,DateInterval和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
回答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;
}
?>

