I am using R and lubridate.
I need to count the number of leap days occurring in a bunch of different date ranges. I have done lots of googling but most results seem to just want to find out if certain years are leap years but do not consider where you are starting and ending within each year, or are for different programs I am not familiar with.
I was thinking a function would be the best way to go but was struggling on getting the code down.
My idea was to count the number of leap years in the date range using lubridate's leap_year
function, and then check the partial years at the beginning and end of the period and add/subtract to the leap year count if needed.
start_date <- as.Date("2008-03-31")
end_date <- as.Date("2020-09-30")
years_list <- seq(start_date, end_date, by="years")
leap_days <- sum(leap_year(years_list))
The next step would be to check the partial years and add/subtract from leap_days
when needed, which is where I am struggling. The desired result for this situation would be 3 (leap years in 2012, 2016, and 2020). Ultimately, I would be checking lots of different date ranges, not just this one.
Any help is appreciated.
CodePudding user response:
If you accept the premise that a "leap day" is always February 29, then perhaps
grep("-02-29", seq(start_date, end_date, by = "day"), value = TRUE)
# [1] "2012-02-29" "2016-02-29" "2020-02-29"
CodePudding user response:
This function seems to work, returning the total count of leap days.
count_leap_days <- function(x){
if(!require(lubridate)){
stop("install package 'lubridate'")
}
first_leap <- if(leap_year(x[1])) month(x[1]) %in% 1:2
x <- x[-1]
n <- length(x)
if(n > 0){
if(leap_year(x[n])) {
last_leap <- (month(x[n]) >= 3) || (month(x[n] == 2 && day(x[n] == 29)))
x <- x[-n]
}
}
ly <- c(first_leap, leap_year(x), last_leap)
sum(ly)
}
count_leap_days(years_list)
#[1] 3