php PHP中给定日期的下一个工作日
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5532002/
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
Next business day of given date in PHP
提问by Marko
Does anyone have a PHP snippet to calculate the next business day for a given date? How does, for example, YYYY-MM-DD need to be converted to find out the next business day?
有没有人有一个 PHP 代码段来计算给定日期的下一个工作日?例如,需要如何转换 YYYY-MM-DD 才能找出下一个工作日?
Example: For 03.04.2011 (DD-MM-YYYY) the next business day is 04.04.2011. For 08.04.2011 the next business day is 11.04.2011.
示例:对于 03.04.2011 (DD-MM-YYYY),下一个工作日是 04.04.2011。对于 08.04.2011,下一个工作日是 11.04.2011。
This is the variable containing the date I need to know the next business day for
这是包含我需要知道下一个工作日的日期的变量
$cubeTime['time'];
Variable contains: 2011-04-01 result of the snippet should be: 2011-04-04
变量包含:2011-04-01 片段的结果应该是:2011-04-04
回答by Dave
Next Weekday
下一个工作日
This finds the next weekday from a specific date (not including Saturday or Sunday):
这将查找特定日期(不包括星期六或星期日)的下一个工作日:
echo date('Y-m-d', strtotime('2011-04-05 +1 Weekday'));
You could also do it with a date variable of course:
当然,您也可以使用日期变量来做到这一点:
$myDate = '2011-04-05';
echo date('Y-m-d', strtotime($myDate . ' +1 Weekday'));
UPDATE:Or, if you have access to PHP's DateTime class(very likely):
更新:或者,如果您有权访问PHP 的 DateTime 类(很可能):
$date = new DateTime('2018-01-27');
$date->modify('+7 weekday');
echo $date->format('Y-m-d');
Want to Skip Holidays?:
想跳过假期?:
Although the original poster mentioned "I don't need to consider holidays", if you DO happen to want to ignore holidays, just remember - "Holidays" is just an array of whatever dates you don't want to include and differs by country, region, company, person...etc.
尽管原始海报提到“我不需要考虑假期”,但如果您碰巧想忽略假期,请记住-“假期”只是您不想包含的任何日期的数组,并且因国家/地区而异,地区,公司,个人...等。
Simply put the above code into a function that excludes/loops past the dates you don't want included. Something like this:
只需将上述代码放入一个函数中,该函数会排除/循环超过您不希望包含的日期。像这样的东西:
$tmpDate = '2015-06-22';
$holidays = ['2015-07-04', '2015-10-31', '2015-12-25'];
$i = 1;
$nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));
while (in_array($nextBusinessDay, $holidays)) {
$i++;
$nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));
}
I'm sure the above code can be simplified or shortened if you want. I tried to write it in an easy-to-understand way.
如果你愿意,我相信上面的代码可以被简化或缩短。我试图以易于理解的方式编写它。
回答by user2412642
For UK holidays you can use
对于英国假期,您可以使用
https://www.gov.uk/bank-holidays#england-and-wales
https://www.gov.uk/bank-holidays#england-and-wales
The ICS format data is easy to parse. My suggestion is...
ICS 格式数据易于解析。我的建议是...
# $date must be in YYYY-MM-DD format
# You can pass in either an array of holidays in YYYYMMDD format
# OR a URL for a .ics file containing holidays
# this defaults to the UK government holiday data for England and Wales
function addBusinessDays($date,$numDays=1,$holidays='') {
if ($holidays==='') $holidays = 'https://www.gov.uk/bank-holidays/england-and-wales.ics';
if (!is_array($holidays)) {
$ch = curl_init($holidays);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$ics = curl_exec($ch);
curl_close($ch);
$ics = explode("\n",$ics);
$ics = preg_grep('/^DTSTART;/',$ics);
$holidays = preg_replace('/^DTSTART;VALUE=DATE:(\d{4})(\d{2})(\d{2}).*/s','--',$ics);
}
$addDay = 0;
while ($numDays--) {
while (true) {
$addDay++;
$newDate = date('Y-m-d', strtotime("$date +$addDay Days"));
$newDayOfWeek = date('w', strtotime($newDate));
if ( $newDayOfWeek>0 && $newDayOfWeek<6 && !in_array($newDate,$holidays)) break;
}
}
return $newDate;
}
回答by mhitza
function next_business_day($date) {
$add_day = 0;
do {
$add_day++;
$new_date = date('Y-m-d', strtotime("$date +$add_day Days"));
$new_day_of_week = date('w', strtotime($new_date));
} while($new_day_of_week == 6 || $new_day_of_week == 0);
return $new_date;
}
This function should ignore weekends (6 = Saturday and 0 = Sunday).
此函数应忽略周末(6 = 星期六和 0 = 星期日)。
回答by John Parker
What you need to do is:
你需要做的是:
Convert the provided date into a timestamp.
Use this along with the or
w
orN
formatters for PHP's datecommand to tell you what day of the week it is.If it isn't a "business day", you can then increment the timestamp by a day (86400 seconds) and check again until you hit a business day.
将提供的日期转换为时间戳。
将它与PHP 的date命令的 or
w
或N
formatters一起使用来告诉您它是一周中的哪一天。如果它不是“工作日”,您可以将时间戳增加一天(86400 秒)并再次检查,直到您到达工作日。
N.B.: For this is reallywork, you'd also need to exclude any bank or public holidays, etc.
注意:因为这确实是工作,您还需要排除任何银行或公共假期等。
回答by Angus
This function will calculate the business day in the future or past. Arguments are number of days, forward (1) or backwards(0), and a date. If no date is supplied todays date will be used:
此函数将计算未来或过去的营业日。参数是天数、向前 (1) 或向后 (0) 和日期。如果没有提供日期,将使用今天的日期:
// returned $date Y/m/d
function work_days_from_date($days, $forward, $date=NULL)
{
if(!$date)
{
$date = date('Y-m-d'); // if no date given, use todays date
}
while ($days != 0)
{
$forward == 1 ? $day = strtotime($date.' +1 day') : $day = strtotime($date.' -1 day');
$date = date('Y-m-d',$day);
if( date('N', strtotime($date)) <= 5) // if it's a weekday
{
$days--;
}
}
return $date;
}
回答by GeniusDesign
I stumbled apon this thread when I was working on a Danish website where I needed to code a "Next day delivery" PHP script.
当我在一个丹麦网站上工作时,我偶然发现了这个线程,我需要编写一个“次日交付”PHP 脚本。
Here is what I came up with (This will display the name of the next working day in Danish, and the next working + 1 if current time is more than a given limit)
这是我想出的(这将用丹麦语显示下一个工作日的名称,如果当前时间超过给定的限制,则下一个工作+1)
$day["Mon"] = "Mandag";
$day["Tue"] = "Tirsdag";
$day["Wed"] = "Onsdag";
$day["Thu"] = "Torsdag";
$day["Fri"] = "Fredag";
$day["Sat"] = "L?rdag";
$day["Sun"] = "S?ndag";
date_default_timezone_set('Europe/Copenhagen');
$date = date('l');
$checkTime = '1400';
$date2 = date(strtotime($date.' +1 Weekday'));
if( date( 'Hi' ) >= $checkTime) {
$date2 = date(strtotime($date.' +2 Weekday'));
}
if (date('l') == 'Saturday'){
$date2 = date(strtotime($date.' +2 Weekday'));
}
if (date('l') == 'Sunday') {
$date2 = date(strtotime($date.' +2 Weekday'));
}
echo '<p>N?ste levering: <span>'.$day[date("D", $date2)].'</span></p>';
As you can see in the sample code $checkTime is where I set the time limit which determines if the next day delivery will be +1 working day or +2 working days.
正如您在示例代码中看到的,$checkTime 是我设置时间限制的地方,该时间限制决定了第二天交货是 +1 个工作日还是 +2 个工作日。
'1400' = 14:00 hours
'1400' = 14:00 小时
I know that the if statements can be made more compressed, but I show my code for people to easily understand the way it works.
我知道可以更压缩 if 语句,但我向人们展示了我的代码,以便人们轻松理解它的工作方式。
I hope someone out there can use this little snippet.
我希望有人可以使用这个小片段。
回答by Suresh Kamrushi
See the example below:
请参阅下面的示例:
$startDate = new DateTime( '2013-04-01' ); //intialize start date
$endDate = new DateTime( '2013-04-30' ); //initialize end date
$holiday = array('2013-04-11','2013-04-25'); //this is assumed list of holiday
$interval = new DateInterval('P1D'); // set the interval as 1 day
$daterange = new DatePeriod($startDate, $interval ,$endDate);
foreach($daterange as $date){
if($date->format("N") <6 AND !in_array($date->format("Y-m-d"),$holiday))
$result[] = $date->format("Y-m-d");
}
echo "<pre>";print_r($result);
For more info: http://goo.gl/YOsfPX
欲了解更多信息:http: //goo.gl/YOsfPX
回答by Ishwor Khadka
You could do something like this.
你可以做这样的事情。
/**
* @param string $date
* @param DateTimeZone|null|null $DateTimeZone
* @return \NavigableDate\NavigableDateInterface
*/
function getNextBusinessDay(string $date, ? DateTimeZone $DateTimeZone = null):\NavigableDate\NavigableDateInterface
{
$Date = \NavigableDate\NavigableDateFacade::create($date, $DateTimeZone);
$NextDay = $Date->nextDay();
while(true)
{
$nextDayIndexInTheWeek = (int) $NextDay->format('N');
// check if the day is between Monday and Friday. In DateTime class php, Monday is 1 and Friday is 5
if ($nextDayIndexInTheWeek >= 1 && $nextDayIndexInTheWeek <= 5)
{
break;
}
$NextDay = $NextDay->nextDay();
}
return $NextDay;
}
$date = '2017-02-24';
$NextBussinessDay = getNextBusinessDay($date);
var_dump($NextBussinessDay->format('Y-m-d'));
Output:
输出:
string(10) "2017-02-27"
\NavigableDate\NavigableDateFacade::create($date, $DateTimeZone)
, is provided by php library available at https://packagist.org/packages/ishworkh/navigable-date. You need to first include this library in your project with composer or direct download.
\NavigableDate\NavigableDateFacade::create($date, $DateTimeZone)
,由https://packagist.org/packages/ishworkh/navigable-date 上的php 库提供。您需要首先使用 composer 或直接下载将这个库包含在您的项目中。
回答by Nishant Bhatt
I used below methods in PHP, strtotime()does not work specially in leap yearFebruarymonth.
我在 PHP 中使用了以下方法,strtotime()在闰年2月不起作用。
public static function nextWorkingDay($date, $addDays = 1)
{
if (strlen(trim($date)) <= 10) {
$date = trim($date)." 09:00:00";
}
$date = new DateTime($date);
//Add days
$date->add(new DateInterval('P'.$addDays.'D'));
while ($date->format('N') >= 5)
{
$date->add(new DateInterval('P1D'));
}
return $date->format('Y-m-d H:i:s');
}
This solution for 5 working days (you can change if you required for 6 or 4 days working). if you want to exclude more days like holidays then just check another condition in while loop.
此解决方案 5 个工作日(如果需要 6 或 4 天的工作,您可以更改)。如果你想排除更多的日子,比如假期,那么只需在 while 循环中检查另一个条件。
//
while ($date->format('N') >= 5 && !in_array($date->format('Y-m-d'), self::holidayArray()))