问题
I need to take a vector of dates and for each date get the first day of the next quarter.
(Or rather, to round to the last day of the current quarter, find the first day of the next quarter and take on off is my plan)
lubridate
will round/ceiling to months, but not quarters
Only solution I've found so far is to make a vector listing all the quarter starts from 1970 to 2099 and then search through that to find the minimum date after my date. Clearly, this vectorises and scales badly.
I need to be able to specify the year end month (although year always starts on 1st of the month)
E.g.
x = as.Date("2014-08-15")
RoundToQuarterStart(x, yearStarts = "March")
[1] "2014-09-01"
Since year starts on 1st March in this example, then Q3 starts 1st September, which is the next quarter start after the given date. (or equivalently this date belongs to Q2 which ends on 31st August)
回答1:
The zoo
package can help for many things date-related including this:
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"
But, that might not get you what you need (there are ways to extrapolate from those values).
The timeDate
package has:
timeFirstDayInQuarter(charvec, format = "%Y-%m-%d", zone = "", FinCenter = "")
timeLastDayInQuarter(charvec, format = "%Y-%m-%d", zone = "", FinCenter = "")
which might make it easer to use and tweak to adjust for different Q1 start origins.
回答2:
I know it’s an old thread but I found my way here from a recent duplicate post.
lubridate::ceiling_date()
now accepts quarters.
回答3:
For any time interval (Annual, Quarterly, Monthly, Weekly), the following function gives the end date, using R base functions (as.POSIXlt and 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"
来源:https://stackoverflow.com/questions/23045866/how-can-i-round-a-date-to-the-quarter-start-end