From 27bfb9700afeaed7de19ecd910785778f438a92d Mon Sep 17 00:00:00 2001 From: Benjamin Schwendinger Date: Tue, 21 Jul 2026 18:47:20 +0200 Subject: [PATCH 1/3] add fix --- NEWS.md | 2 ++ R/IDateTime.R | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 025e9a5789..6693cee54d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -62,6 +62,8 @@ 13. `rbindlist()` (and therefore the `rbind()` method for `data.table`s) no longer raises an error upon encountering more than approximately 50000 columns in a list entry, [#7793](https://github.com/Rdatatable/data.table/issues/7793). The bug was introduced in `data.table` version 1.18.2.1. Thanks to @rickhelmus for the report and @aitap for the fix. +14. Subtracting an `IDate` from a `Date` is fast again by avoiding unnecessary conversion to `POSIXlt`/`POSIXct`, [#7825](https://github.com/Rdatatable/data.table/issues/7825). Thanks @gilesheywood for the report and @ben-schwen for the fix. + ### Notes 1. {data.table} now depends on R 3.5.0 (2018). diff --git a/R/IDateTime.R b/R/IDateTime.R index 63588e7754..2727070251 100644 --- a/R/IDateTime.R +++ b/R/IDateTime.R @@ -111,7 +111,16 @@ chooseOpsMethod.IDate = function(x, y, mx, my, cl, reverse) inherits(y, "Date") `-.IDate` = function(e1, e2) { if (!inherits(e1, "IDate")) { - if (inherits(e1, 'Date')) return(base::`-.Date`(e1, e2)) + if (inherits(e1, "Date")) { + if (inherits(e2, "Date")) { + #7825 avoid base::`-.Date` to avoid conversion from IDate to POSIXlt/POSIXct + ans = unclass(e1) - unclass(e2) + setattr(ans, "class", "difftime") + setattr(ans, "units", "days") + return(ans) + } + return(base::`-.Date`(e1, e2)) + } stopf("can only subtract from \"IDate\" objects") } if (storage.mode(e1) != "integer") From 0d1dfbc82f52f339ea59a42236fc7263e70e1ad8 Mon Sep 17 00:00:00 2001 From: Benjamin Schwendinger Date: Fri, 24 Jul 2026 09:53:29 +0200 Subject: [PATCH 2/3] reregister more --- .ci/atime/tests.R | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.ci/atime/tests.R b/.ci/atime/tests.R index d8fad8cc2f..f1c5e017e7 100644 --- a/.ci/atime/tests.R +++ b/.ci/atime/tests.R @@ -421,14 +421,17 @@ test.list <- atime::atime_test_list( expr = { ns = environment(data.table::as.IDate) s3_table = get(".__S3MethodsTable__.", envir = baseenv()) - if (exists("chooseOpsMethod.IDate", envir = s3_table)) { - rm("chooseOpsMethod.IDate", envir = s3_table) - } - if (exists("chooseOpsMethod.IDate", envir = ns, inherits = FALSE)) { - base::registerS3method( - "chooseOpsMethod", "IDate", - get("chooseOpsMethod.IDate", envir = ns), - envir = ns) + s3_generics = c("chooseOpsMethod.IDate" = "chooseOpsMethod", "-.IDate" = "-") + for (s3_method in names(s3_generics)) { + if (exists(s3_method, envir = s3_table, inherits = FALSE)) { + rm(list = s3_method, envir = s3_table) + } + if (exists(s3_method, envir = ns, inherits = FALSE)) { + base::registerS3method( + s3_generics[[s3_method]], "IDate", + get(s3_method, envir = ns, inherits = FALSE), + envir = ns) + } } outer(short_date, data.table::as.IDate(long_date), `-`) }), From b6bca2aadb4c89033b676f65707e256d975123e5 Mon Sep 17 00:00:00 2001 From: Benjamin Schwendinger <52290390+ben-schwen@users.noreply.github.com> Date: Sat, 25 Jul 2026 08:58:53 +0200 Subject: [PATCH 3/3] unnest with early return Co-authored-by: Michael Chirico --- R/IDateTime.R | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/R/IDateTime.R b/R/IDateTime.R index 2fffbcd05d..7f21926714 100644 --- a/R/IDateTime.R +++ b/R/IDateTime.R @@ -112,14 +112,12 @@ chooseOpsMethod.IDate = function(x, y, mx, my, cl, reverse) inherits(y, "Date") `-.IDate` = function(e1, e2) { if (!inherits(e1, "IDate")) { if (inherits(e1, "Date")) { - if (inherits(e2, "Date")) { - #7825 avoid base::`-.Date` to avoid conversion from IDate to POSIXlt/POSIXct - ans = unclass(e1) - unclass(e2) - setattr(ans, "class", "difftime") - setattr(ans, "units", "days") - return(ans) - } - return(base::`-.Date`(e1, e2)) + if (!inherits(e2, "Date")) return(base::`-.Date`(e1, e2)) + #7825 avoid base::`-.Date` to avoid conversion from IDate to POSIXlt/POSIXct + ans = unclass(e1) - unclass(e2) + setattr(ans, "class", "difftime") + setattr(ans, "units", "days") + return(ans) } stopf("can only subtract from \"IDate\" objects") }