Skip to content

Commit c073b81

Browse files
mikmartvspinu
authored andcommitted
Implement leap_year() in C
1 parent f8773fc commit c073b81

File tree

4 files changed

+28
-1
lines changed

4 files changed

+28
-1
lines changed

R/leap-years.r

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,5 @@ leap_year <- function(date) {
2121
} else {
2222
year <- year(date)
2323
}
24-
(year %% 4 == 0) & ((year %% 100 != 0) | (year %% 400 == 0))
24+
.Call(C_is_leap_year, as.integer(year))
2525
}

src/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ extern SEXP C_make_d(SEXP, SEXP, SEXP);
88
extern SEXP C_parse_dt(SEXP, SEXP, SEXP, SEXP, SEXP);
99
extern SEXP C_parse_hms(SEXP, SEXP);
1010
extern SEXP C_parse_period(SEXP);
11+
extern SEXP C_is_leap_year(SEXP);
1112

1213
static const R_CallMethodDef CallEntries[] = {
1314
{"C_make_d", (DL_FUNC) &C_make_d, 3},
1415
{"C_parse_dt", (DL_FUNC) &C_parse_dt, 5},
1516
{"C_parse_hms", (DL_FUNC) &C_parse_hms, 2},
1617
{"C_parse_period", (DL_FUNC) &C_parse_period, 1},
18+
{"C_is_leap_year", (DL_FUNC) &C_is_leap_year, 1},
1719
{NULL, NULL, 0}
1820
};
1921

src/utils.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,27 @@
2727
#include <ctype.h>
2828
#include <Rinternals.h>
2929

30+
SEXP C_is_leap_year(SEXP year) {
31+
if(!isInteger(year)) error("year must be integer");
32+
33+
R_len_t n = LENGTH(year);
34+
int* pyear = INTEGER(year);
35+
36+
SEXP res = allocVector(LGLSXP, n);
37+
int *data = LOGICAL(res);
38+
39+
for(int i = 0; i < n; i++) {
40+
int y = pyear[i];
41+
if(y == NA_INTEGER) {
42+
data[i] = NA_LOGICAL;
43+
} else {
44+
data[i] = IS_LEAP(y);
45+
}
46+
}
47+
48+
return res;
49+
}
50+
3051
// return adjustment (in seconds) due to leap years
3152
// y: years after (positive) or before (negative) 2000-01-01 00:00:00
3253
int adjust_leap_years(int y, int m, int is_leap){

tests/testthat/test-utilities.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ test_that("leap_year correctly identifies leap years", {
66
expect_true(leap_year(y))
77
})
88

9+
test_that("leap_year handles missing values", {
10+
expect_equal(leap_year(NA), NA)
11+
})
12+
913
test_that("leap_year handles various date-time vectors", {
1014
x <- as.POSIXct(c("2008-08-03 12:01:59", "2009-08-03 12:01:59"), tz = "UTC")
1115

0 commit comments

Comments
 (0)