diff --git a/NEWS.md b/NEWS.md index f7faf06b6..862111f57 100644 --- a/NEWS.md +++ b/NEWS.md @@ -288,6 +288,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 b2142520d..a8277b2e7 100644 --- a/inst/tests/tests.Rraw +++ b/inst/tests/tests.Rraw @@ -18381,7 +18381,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)) @@ -21685,3 +21685,9 @@ d3 = unserialize(serialize(d2, NULL)) test(2340.05, .selfref.ok(d3), FALSE) setDT(d3) test(2340.06, .selfref.ok(d3), TRUE) + +# week() sequential numbering fix tests #2611 +test(2341.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(2341.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(2341.3, week(as.IDate(c("2019-12-31","2020-01-01"))), c(53L,1L)) # year boundary non-leap → reset to 1 +test(2341.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; }