26

我正在寻找可靠地加上和减去六个月(债券时间)lubridate

例如,将六个月添加到应12/31/2014导致6/30/2015,添加到2/28/2014应导致8/31/2014

, 的问题as.Date("2014-12-31") + months(6)是它产生一个NA. 或者,第二个结果是 2014 年 8 月 28 日,因为它不只是将 6 个月添加到月份,然后知道一天应该在哪里结束取决于月份。

有什么办法可以快速纠正这个问题吗?目前,我正在构建一个基本上使用开关并考虑每个月的功能,但这很长,我也遇到了问题。

谢谢!

4

2 回答 2

69

lubridate功能%m+%可能在这里有用:

在不超过新月份的最后一天的情况下对日期添加和减去月份

as.Date("2014-12-31") %m+% months(6)
# [1] "2015-06-30"

要处理第二种情况,您需要使用 向上舍入到最接近的月份ceiling_date,并使用 减去一天days

ceiling_date(as.Date("2014-02-28") %m+% months(6), unit = "month") - days(1)
# [1] "2014-08-31"
于 2014-03-25T20:53:45.837 回答
2

我只是快速编写了代码,但我认为它应该可以工作。但是,我不确定这是否是最优雅的解决方案。

# up = 1, down = -1
six.mo.mover<-function(date,up.or.down) {
  last.day <- month(date) != month(as.Date(date)+1) 
  if(last.day) {
    adj.date <- as.Date(date) - day(as.Date(date)-1) + up.or.down*months(6)
    adj.mo <- month(adj.date)
    if (adj.mo == 2) {
      dy <- 28 + leap_year(year(adj.date))
    }
    else {
      dy <- 31-(adj.mo-1)%%7%%2
    }
    adj.date + days(dy-1)
  } 
  else {
    as.Date(date)+up.or.down*months(6)
  }
}

注意:没有调试,所以自己检查并告诉我。

于 2014-03-25T08:57:46.857 回答