Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

End of previous quarter / last day of previous quarter

Using lubridate, how to calculate the last day of the previous quarter for a given date? The below formula doesn't seem to work for Nov 3rd, 2014 (other dates work)

library(lubridate)
date = as.POSIXct("2014-11-03")
date - days(day(date)) - months(month(date) %% 3 - 1)
# NA

Interesting enough, changing order works:

date - months(month(date) %% 3 - 1) - days(day(date))
# "2014-09-30 UTC"
like image 404
Daniel Krizian Avatar asked Feb 12 '23 13:02

Daniel Krizian


1 Answers

Here are some possibilities with functions from packages zoo and timeDate, and base R. The zoo code was improved by @G.Grothendieck, and he also suggested the base alternative (thanks a lot!). I leave the lubridate solution(s) to someone else.

First, use class yearqtr in package zoo to represent the quarterly data. You may then use as.Date.yearqtr and the frac argument "which is a number between 0 and 1 inclusive that indicates the fraction of the way through the period that the result represents. The default is 0 which means the beginning of the period" (see ?yearqtr, and ?yearmon for frac).

Step by step:

library(zoo)

date <- as.Date("2014-11-03")

# current quarter
current_q <- as.yearqtr(date)
current_q
# [1] "2014 Q4"

# first date in current quarter
first_date_current_q <- as.Date(current_q, frac = 0)
first_date_current_q 
# [1] "2014-10-01"

# last date in previous quarter
last_date_prev_q <- first_date_current_q - 1
last_date_prev_q
# [1] "2014-09-30"

And a short version by @G.Grothendieck (thanks!)

as.Date(as.yearqtr(date)) - 1
# [1] "2014-09-30"

A nice base R solution by @G.Grothendieck

as.Date(cut(date, "quarter")) - 1
# [1] "2014-09-30"

Another possibility is to use timeFirstDayInQuarter and timeLastDayInQuarter functions in package timeDate:

library(timeDate)
timeLastDayInQuarter(timeFirstDayInQuarter(date) - 1)
# GMT
# [1] [2014-09-30]
like image 107
Henrik Avatar answered Feb 24 '23 18:02

Henrik