如何计算网络日减去2个日期之间的假期

时间:2017-11-03 17:59:16

标签: r excel-formula

我试图了解如何在Excel中应用NETWORKDAYS之类的函数。我花了一些时间搜索并找到了一些例子,但却无法让1工作。

示例1:

library(lubridate)
Date1 <- dmy("01/04/2017")
Date2 <- dmy("28/04/2017")
sum(!weekdays(seq(Date1, Date2, "days")) %in% c("Saturday", "Sunday"))

这样可行,但需要删除假期

示例2:

workdays = function(iniDate, endDate, holidays) {
  theDates = seq(from=iniDate,to=endDate,by="day")
  isHoliday = theDates %in% holidays
  isWeekend = (as.POSIXlt(theDates)$wday) %in% (c(0,6))
  return (sum(!isHoliday & !isWeekend))
}

这似乎是我最好的选择但是我无法锻炼如何创建银行假日矢量以应用于功能。

有人可以告诉我如何使用此功能或更好的方法计算2个日期(节假日除外)之间的工作日?

1 个答案:

答案 0 :(得分:1)

我认为你很接近:如果从2017-04-012017-04-28的天数为:

allDays <- seq.Date(from=as.Date("2017-04-01"), to=as.Date("2017-04-28"), by=1)

来自:

的假期矢量
easter <- c(as.Date("2017-04-15"), as.Date("2017-04-16"), as.Date("2017-04-17"))

然后您可以使用setdiff功能删除假期:

nonHolidays <- as.Date(setdiff(allDays, easter ), origin="1970-01-01")

使用与第一个示例类似的方法,周末将返回:

weekends <- nonHolidays[weekdays(nonHolidays) %in% c("Saturday", "Sunday")]

可以再次使用setdiff从非假期中删除周末:

nonHolidaysWeekends <- as.Date(setdiff(nonHolidays, weekends), origin="1970-01-01")

因此,您可以将其包装在返回nonHolidaysWeekends的长度的函数中:

networkDays <- function(beginDate, endDate, holidayDates) {
  # get all days between beginDate and endDate
  allDays <- seq.Date(from=beginDate, to=endDate, by=1)
  # use setdiff to remove holidayDates and convert back to date vector
  nonHolidays <- as.Date(setdiff(allDays, holidayDates), origin="1970-01-01")
  # find all weekends left in nonHolidays
  weekends <- nonHolidays[weekdays(nonHolidays) %in% c("Saturday", "Sunday")]
  # use setdiff again to remove the weekends from nonHolidays and convert back to date vector
  nonHolidaysWeekends <- as.Date(setdiff(nonHolidays, weekends), origin="1970-01-01")
  # return length of vector filtered for holidays and weekends
  length(nonHolidaysWeekends)
}

d1 <- as.Date("2017-04-01")
d2 <- as.Date("2017-04-28")
# includes Easter Sunday
easter <- c(as.Date("2017-04-15"), as.Date("2017-04-16"), as.Date("2017-04-17"))
networkDays(d1, d2, easter)

如果感兴趣的话,还有类似的问题here