Как я могу округлить дату до начала/конца квартала?

мне нужно взять вектор времени и для каждого дня первый день следующего квартала.

(вернее, для округления до последнего дня текущего квартала, найти первый день следующего квартала и взять на мой план)

lubridate будет круглый / потолок до месяцев, но не четверти

единственное решение, которое я нашел до сих пор, - это сделать векторный список всех кварталов с 1970 по 2099 год, а затем выполнить поиск, чтобы найти минимальную дату после мое свидание. Понятно, что это vectorises и плохо масштабируется.

мне нужно иметь возможность указать месяц конца года (хотя год всегда начинается с 1-го числа месяца)

Э. Г.

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

поскольку год начинается 1 марта в этом примере, то Q3 начинается 1 сентября, что является следующим кварталом после заданной даты. (или, что эквивалентно, эта дата принадлежит Q2, который заканчивается 31 августа)

2 ответов


на 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"

но это может не дать вам то, что вам нужно (есть способы экстраполировать из этих значений).

на есть:

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

что может сделать его более легким в использовании и настройке для настройки для разных источников запуска Q1.


для любого интервала времени (годовой, квартальный, ежемесячный, Еженедельный), следующая функция дает дату окончания, используя базовые функции R (as.POSIXlt и as.Дата):

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"