我们有一个基于PHP的时间表系统,该系统已在内部开发,并且多年来不断发展,但向用户提供的一条信息是每个项目剩余的工作日数。
目前,我只是采用当前日期和项目结束日期之间的差异,然后除以7并乘以5.这已经足够长时间,对于周一至周五全职工作的员工来说,大部分都是准确的。但是,我们现在有一些工作人员每周只工作一天。
时间表系统知道员工工作的日期,此信息存储在用户类的字符串中,对于全职工作人员,值为NNYYYYY
(表示ssMTWTF
)
通过将两个日期之间的差异除以7,然后乘以他们工作的天数,我可以非常轻松地使结果更准确,但是在进行此更改时,我考虑生产更多更准确的计算实际价值的方法。
最让人想到的方法是在两个日期之间使用一个循环,将星期几与用户的工作模式进行比较,在用户工作的日子将一个添加到计数器一天。
由于时间表上的项目数量,项目每页浏览量平均需要执行大约30次,并且项目一次可能跨越12个月或18个月(每个项目的循环次数很多)页面加载),我想知道是否有更好的方法在PHP中执行此操作?
答案 0 :(得分:9)
这段代码可能会有所帮助:
<?php
//get current month for example
$beginday = date("Y-m-01");
$lastday = date("Y-m-t");
$nr_work_days = getWorkingDays($beginday, $lastday);
echo $nr_work_days;
function getWorkingDays($startDate, $endDate)
{
$begin = strtotime($startDate);
$end = strtotime($endDate);
if ($begin > $end) {
echo "startdate is in the future! <br />";
return 0;
} else {
$no_days = 0;
$weekends = 0;
while ($begin <= $end) {
$no_days++; // no of days in the given interval
$what_day = date("N", $begin);
if ($what_day > 5) { // 6 and 7 are weekend days
$weekends++;
};
$begin += 86400; // +1 day
};
$working_days = $no_days - $weekends;
return $working_days;
}
}
另一种解决方案可以是: Get date range between two dates excluding weekends
答案 1 :(得分:2)
您可以使用以下功能查找工作日数。
您可以在此处查看LIVE DEMO。
function number_of_working_days($startDate, $endDate)
{
$workingDays = 0;
$startTimestamp = strtotime($startDate);
$endTimestamp = strtotime($endDate);
for ($i = $startTimestamp; $i <= $endTimestamp; $i = $i + (60 * 60 * 24)) {
if (date("N", $i) <= 5) $workingDays = $workingDays + 1;
}
return $workingDays;
}
答案 2 :(得分:1)
如果您想查找两个日期与工作日选项之间的总工作日。那么这将有所帮助
$startDate = '2016-10-01';
$endDate = '2016-10-31';
$weekdays = array('1','2','3','4','5','6'); //this i think monday-saturday
$begin = new DateTime($startDate);
$end = new DateTime($endDate);
$end = $end->modify( '+1 day' ); //add one day so as to include the end date of our range
$interval = new DateInterval('P1D'); // 1 Day
$dateRange = new DatePeriod($begin, $interval, $end);
$total_days = 0;
//this will calculate total days from monday to saturday in above date range
foreach ($dateRange as $date) {
if (in_array($date->format("N"),$weekdays)) {
$total_days++;
}
}
答案 3 :(得分:0)
我尝试了一些解决方案,它们对我不起作用(给我的结果包括周末),所以我把它写成一个解决方案:
function number_of_working_days($from, $to) {
$target = strtotime($from);
$days = 0;
while ($target < strtotime(date("Y-m-d",strtotime($to)))) {
if(date("N",$target) <= 5) $days++;
$target += (60*60*24); /* move forward by 1 day */
}
return $days;
}
$from
和$to
是mySQL表中的日期。
答案 4 :(得分:0)
function workingDaysBetweenDates(startDate, endDate) {
// Validate input
if (endDate < startDate)
return 0;
// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);
// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);
// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();
// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;
// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6) {
days = days - 1;
}
// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0) {
days = days - 1;
}
return days;
}
$('#results').html(workingDaysBetweenDates(new Date('6/03/2019'), new Date('6/17/2019')));
希望这会有所帮助。