Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion R/leap-years.r
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ leap_year <- function(date) {
} else {
year <- year(date)
}
(year %% 4 == 0) & ((year %% 100 != 0) | (year %% 400 == 0))
.Call(C_is_leap_year, as.integer(year))
}
2 changes: 2 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ extern SEXP C_make_d(SEXP, SEXP, SEXP);
extern SEXP C_parse_dt(SEXP, SEXP, SEXP, SEXP, SEXP);
extern SEXP C_parse_hms(SEXP, SEXP);
extern SEXP C_parse_period(SEXP);
extern SEXP C_is_leap_year(SEXP);

static const R_CallMethodDef CallEntries[] = {
{"C_make_d", (DL_FUNC) &C_make_d, 3},
{"C_parse_dt", (DL_FUNC) &C_parse_dt, 5},
{"C_parse_hms", (DL_FUNC) &C_parse_hms, 2},
{"C_parse_period", (DL_FUNC) &C_parse_period, 1},
{"C_is_leap_year", (DL_FUNC) &C_is_leap_year, 1},
{NULL, NULL, 0}
};

Expand Down
21 changes: 21 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,27 @@
#include <ctype.h>
#include <Rinternals.h>

SEXP C_is_leap_year(SEXP year) {
if(!isInteger(year)) error("year must be integer");

R_len_t n = LENGTH(year);
int* pyear = INTEGER(year);

SEXP res = allocVector(LGLSXP, n);
int *data = LOGICAL(res);

for(int i = 0; i < n; i++) {
int y = pyear[i];
if(y == NA_INTEGER) {
data[i] = NA_LOGICAL;
} else {
data[i] = IS_LEAP(y);
}
}

return res;
}

// return adjustment (in seconds) due to leap years
// y: years after (positive) or before (negative) 2000-01-01 00:00:00
int adjust_leap_years(int y, int m, int is_leap){
Expand Down
4 changes: 4 additions & 0 deletions tests/testthat/test-utilities.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ test_that("leap_year correctly identifies leap years", {
expect_true(leap_year(y))
})

test_that("leap_year handles missing values", {
expect_equal(leap_year(NA), NA)
})

test_that("leap_year handles various date-time vectors", {
x <- as.POSIXct(c("2008-08-03 12:01:59", "2009-08-03 12:01:59"), tz = "UTC")

Expand Down
Loading