如何将日期四舍五入到季度开始/结束?

时间:2014-04-13 17:23:56

标签: r date rounding

我需要采用日期矢量,并且每个日期都会到达下一季度的第一天。

(或者更确切地说,到本季度的最后一天,找到下一季度的第一天并取消关闭是我的计划)

lubridate将围绕/上限到几个月,但不是四分之一

到目前为止,我找到的唯一解决方案是制作一个矢量列表从1970年到2099年的所有季度开始,然后搜索它以找到我的约会后的最短日期。显然,这会导致严重的矢量化和扩展。

我需要能够指定年末月份(尽管年份始终从月份的1月开始)

E.g。

x = as.Date("2014-08-15")
RoundToQuarterStart(x, yearStarts = "March")
[1] "2014-09-01"

在本例中,从3月1日开始,然后Q3从9月1日开始,这是在给定日期之后的下一个季度开始。 (或相当于此日期属于Q2,并于8月31日结束)

3 个答案:

答案 0 :(得分:11)

zoo包可以帮助处理与日期相关的许多事情,包括:

library(zoo)

as.yearqtr("2014-08-15", format="%Y-%m-%d")
## [1] "2014 Q3"

as.Date(as.yearqtr("2014-08-15", format="%Y-%m-%d"))
## [1] "2014-07-01"

但是,这可能无法满足您的需求(有办法从这些值中推断出来)。

timeDate包具有:

timeFirstDayInQuarter(charvec, format = "%Y-%m-%d", zone = "", FinCenter = "")
timeLastDayInQuarter(charvec, format = "%Y-%m-%d", zone = "", FinCenter = "")

可能会更容易使用和调整以适应不同的Q1起始点。

答案 1 :(得分:1)

对于任何时间间隔(年度,季度,每月,每周),以下函数使用R基函数(as.POSIXlt和as.Date)给出结束日期:

endDate <- function(date, interval) {
    date.lt <- as.POSIXlt(date) 
    switch(interval, 
           A = {
                date.lt$mon = 11
                date.lt$mday=31
                date=as.Date(date.lt)
            },
           Q = {
                date.lt$mon = (date.lt$mon %/% 3 +1)*3 %% 12 
                date.lt$mday = 1
                date.lt$year = date.lt$year + as.integer(date.lt$mon==0)
                date=as.Date(date.lt)-1
            },
           M = {
                date.lt$mon = (date.lt$mon+1) %% 12
                date.lt$mday = 1
                date.lt$year = date.lt$year + as.integer(date.lt$mon==0)
                date=as.Date(date.lt)-1
            },
           D = {
               date = as.Date(date)
            },
           W = {
               date = as.Date(date)+6-date.lt$wday
           },
           date = as.Date(date$lt)
    )
    date
}
###
endDate (c("2003-05-21","1945-03-29), "M")
# "2003-05-31" "1945-03-31"
endDate (c("2003-05-21","1945-03-29), "M")
#"2003-06-30" "1945-03-31"

答案 2 :(得分:1)

我知道这是一个旧线程,但是我从最近的重复帖子中找到了自己的出路。

lubridate::ceiling_date()现在接受季度。