diff --git a/NEWS.md b/NEWS.md index 303a049a2..52fd5a70b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -197,6 +197,8 @@ 19. Ellipsis elements like `..1` are correctly excluded when searching for variables in "up-a-level" syntax inside `[`, [#5460](https://github.com/Rdatatable/data.table/issues/5460). Thanks @ggrothendieck for the report and @MichaelChirico for the fix. +20. `week()` now calculates the week of the year sequentially, where days 1-7 are always week 1. This fixes a long-standing bug where the first week of the year was incorrectly calculated as having only 6 days, [#2611](https://github.com/Rdatatable/data.table/issues/2611). Thanks to @MichaelChirico for the report and @venom1204 for the fix. + ### NOTES 1. The following in-progress deprecations have proceeded: diff --git a/inst/tests/tests.Rraw b/inst/tests/tests.Rraw index 05e0b5017..0da715e22 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18363,7 +18363,7 @@ x = c("1111-11-11", "2019-01-01", "2019-02-28", "2019-03-01", "2019-12-31", "202 test(2236.1, yday(x), c(315L, 1L, 59L, 60L, 365L, 60L, 61L, 366L, 1L, 366L, 60L, NA)) test(2236.2, mday(x), c(11L, 1L, 28L, 1L, 31L, 29L, 1L, 31L, 1L, 31L, 1L, NA)) test(2236.3, wday(x), c(7L, 3L, 5L, 6L, 3L, 7L, 1L, 5L, 1L, 2L, 2L, NA)) -test(2236.4, week(x), c(46L, 1L, 9L, 9L, 53L, 9L, 9L, 53L, 1L, 53L, 9L, NA)) +test(2236.4, week(x), c(45L, 1L, 9L, 9L, 53L, 9L, 9L, 53L, 1L, 53L, 9L, NA)) test(2236.5, month(x), c(11L, 1L, 2L, 3L, 12L, 2L, 3L, 12L, 1L, 12L, 3L, NA)) test(2236.6, quarter(x), c(4L, 1L, 1L, 1L, 4L, 1L, 1L, 4L, 1L, 4L, 1L, NA)) test(2236.7, year(x), c(1111L, 2019L, 2019L, 2019L, 2019L, 2020L, 2020L, 2020L, 2040L, 2040L, 2100L, NA)) @@ -21655,3 +21655,9 @@ local({ ...123 = 'a' test(2339.11, DT[, .....123], DT) }) + +# week() sequential numbering fix tests #2611 +test(2340.1, week(as.IDate("1970-01-01") + 0:7), c(1L,1L,1L,1L,1L,1L,1L,2L)) # Jan 1–7 all week 1, Jan 8 week 2 +test(2340.2, week(as.IDate(c("2012-02-28","2012-02-29","2012-03-01"))), c(9L,9L,9L)) # leap day stays in same week +test(2340.3, week(as.IDate(c("2019-12-31","2020-01-01"))), c(53L,1L)) # year boundary non-leap → reset to 1 +test(2340.4, week(as.IDate(c("2020-12-31","2021-01-01"))), c(53L,1L)) # year boundary leap → reset to 1 diff --git a/src/idatetime.c b/src/idatetime.c index eaeb35a96..e0b52a6e7 100644 --- a/src/idatetime.c +++ b/src/idatetime.c @@ -64,7 +64,7 @@ void convertSingleDate(int x, datetype type, void *out) yday -= YEARS1 + leap; *(int *)out = ++yday; if (type == WEEK) - *(int *)out = (*(int *)out / 7) + 1; + *(int *)out = ((*(int *)out - 1) / 7) + 1; return; }