如何为特定范围生成(业务)月末/开始?

时间:2015-11-18 21:37:49

标签: r

我有兴趣在一段时间内生成一系列月末或开始。如果日期是工作日,周日或周六不会下降,那就更好了。你是如何在R中做到的?

1 个答案:

答案 0 :(得分:3)

这是我用于该任务的两个函数:

library(lubridate)
# returns a sequence of Business Month Ends between two inputs (inclusive)
# or for the one input

GetBizMonthEndFor <- function(dateChar1, dateChar2 = dateChar1){
  # generate the sequence of month starts
  dateChar <- seq(floor_date(as.Date(dateChar1), unit = "month"), 
                  floor_date(as.Date(dateChar2), unit = "month"), 
                  by = "month")
  # add a month to each sequence element and subtract a day           
  dateChar <- dateChar  + months(1) - days(1)
  # if the day is saturday or sunday, subtract a day or two to hit the 
  # previous friday
  dateChar[wday(dateChar) == 1] <- dateChar[wday(dateChar) == 1] - days(2)
  dateChar[wday(dateChar) == 7] <- dateChar[wday(dateChar) == 7] - days(1)
  dateChar
} 



# returns a sequence of Business Month Starts between two inputs (inclusive)
# or for the one input
GetBizMonthStartFor <- function(dateChar1, dateChar2 = dateChar1){
  # generate the sequence of month starts
  dateChar <- seq(floor_date(as.Date(dateChar1), unit = "month"), 
                  floor_date(as.Date(dateChar2), unit = "month"), 
                  by = "month")
  # January 1 is a holiday, so if the month start is january 1, make
  # January 2 the business month start
  dateChar[month(dateChar) == 1 & day(dateChar) == 1] <- 
      dateChar[month(dateChar) == 1 & day(dateChar) == 1] + days(1)
  # If the day is a saturday or sunday, add a day or two to hit the next
  # monday
  dateChar[wday(dateChar) == 1] <- dateChar[wday(dateChar) == 1] + days(1)
  dateChar[wday(dateChar) == 7] <- dateChar[wday(dateChar) == 7] + days(2)

  dateChar
} 

请注意,营业月份开始时有一个“全球营业日”逻辑。如果这一天是新年,那么这不是一个工作日。您可以将其删除,以便工作日取决于工作日。现在表明它们有效:

> GetBizMonthEndFor("2015-01-12", "2015-10-12")
[1] "2015-01-30" "2015-02-27" "2015-03-31" "2015-04-30" "2015-05-29" "2015-06-30"
[7] "2015-07-31" "2015-08-31" "2015-09-30" "2015-10-30"

请注意,输入日期的日期并不重要,它需要输入的月份,并将它们更改为月份序列的末尾。我还没有提出逻辑,只是在输入值之间只包含月末/开始日期,但这不是一个难以解决的问题。但是,添加的东西是能够通过仅使用一个输入而不是两个输入来检查日期的月末/开始。

> GetBizMonthStartFor("2015-11-01")
[1] "2015-11-02"