Skip to content

Commit a3ba098

Browse files
r2evansBill EvansBill EvansMichaelChirico
authored
fix #6898, disable checking timezone in between() (#6920)
* fix #6898, disable checking timezone in `between()` * reduce tests to simply `between()` * code review * restructure test * del outdated comment * inline lambda * sync \usage * explicit typing --------- Co-authored-by: Bill Evans <[email protected]> Co-authored-by: Bill Evans <[email protected]> Co-authored-by: Michael Chirico <[email protected]>
1 parent f3f7ce0 commit a3ba098

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
5. `as.data.table()` is slightly more efficient at converting arrays to data.tables, [#7019](https://github.com/Rdatatable/data.table/pull/7019). Thanks @eliocamp.
1818

19+
6. `between()` gains the argument `ignore_tzone=FALSE`. Normally, a difference in time zone between `lower` and `upper` will produce an error, and a difference in time zone between `x` and either of the others will produce a message. Setting `ignore_tzone=TRUE` bypasses the checks, allowing both comparisons to proceed without error or message about time zones.
20+
1921
### BUG FIXES
2022

2123
1. Custom binary operators from the `lubridate` package now work with objects of class `IDate` as with a `Date` subclass, [#6839](https://github.com/Rdatatable/data.table/issues/6839). Thanks @emallickhossain for the report and @aitap for the fix.

R/between.R

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# is x[i] in between lower[i] and upper[i] ?
2-
between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE) {
2+
between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE, ignore_tzone=FALSE) {
33
if (is.logical(x)) stopf("between has been passed an argument x of type logical")
44
if (is.logical(lower)) lower = as.integer(lower) # typically NA (which is logical type)
55
if (is.logical(upper)) upper = as.integer(upper) # typically NA (which is logical type)
@@ -16,15 +16,12 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
1616
stopifnot(is.px(x), is.px(lower), is.px(upper)) # nocov # internal
1717
}
1818
# POSIX check timezone match
19-
if (is.px(x) && is.px(lower) && is.px(upper)) {
20-
tzs = sapply(list(x,lower,upper), function(x) {
21-
attr(x, "tzone", exact=TRUE) %||% ""
22-
})
19+
if (!ignore_tzone && is.px(x) && is.px(lower) && is.px(upper)) {
20+
tzs = vapply_1c(list(x, lower, upper), function(x) attr(x, "tzone", exact=TRUE) %||% "")
2321
# lower/upper should be more tightly linked than x/lower, so error
2422
# if the former don't match but only inform if they latter don't
2523
if (tzs[2L]!=tzs[3L]) {
2624
stopf("'between' lower= and upper= are both POSIXct but have different tzone attributes: %s. Please align their time zones.", brackify(tzs[2:3], quote=TRUE))
27-
# otherwise the check in between.c that lower<=upper can (correctly) fail for this reason
2825
}
2926
if (tzs[1L]!=tzs[2L]) {
3027
messagef("'between' arguments are all POSIXct but have mismatched tzone attributes: %s. The UTC times will be compared.", brackify(tzs, quote=TRUE))

inst/tests/tests.Rraw

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21133,3 +21133,10 @@ test(2315.1, tail(DT[order(i), i], 2L), 1:2)
2113321133
# wider range of numbers needed for further coverage
2113421134
DT[1L, i := 1000L]
2113521135
test(2315.2, tail(DT[order(i), i], 2L), c(1L, 1000L))
21136+
21137+
# issue #6898, test that tzone behavior changes with ignore_tzone=TRUE
21138+
tms = list(.POSIXct(1), .POSIXct(1.0, "UTC"))
21139+
test(2316.1, between(tms[[1]], tms[[1L]], tms[[2L]]), error = "different tzone attributes")
21140+
test(2316.2, between(tms[[1]], tms[[1L]], tms[[2L]], ignore_tzone=TRUE))
21141+
test(2316.3, between(tms[[1]], tms[[2L]], tms[[2L]]), message = "mismatched tzone attributes")
21142+
test(2316.4, between(tms[[1]], tms[[2L]], tms[[2L]], ignore_tzone=TRUE))

man/between.Rd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This can be changed by setting \code{NAbounds} to \code{NA}.
1616
the intervals provided in \code{lower,upper}.
1717
}
1818
\usage{
19-
between(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE)
19+
between(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE, ignore_tzone=FALSE)
2020
x \%between\% y
2121

2222
inrange(x, lower, upper, incbounds=TRUE)
@@ -35,6 +35,7 @@ interpreted as \code{lower} and \code{y[[2]]} as \code{upper}.}
3535
It is set to \code{TRUE} by default for infix notations.}
3636
\item{NAbounds}{ If \code{lower} (\code{upper}) contains an \code{NA} what should \code{lower<=x} (\code{x<=upper}) return? By default \code{TRUE} so that a missing bound is interpreted as unlimited. }
3737
\item{check}{ Produce error if \code{any(lower>upper)}? \code{FALSE} by default for efficiency, in particular type \code{character}. }
38+
\item{ignore_tzone}{ \code{TRUE} means skip timezone checks among \code{x}, \code{lower}, and \code{upper}. }
3839
}
3940
\details{
4041

0 commit comments

Comments
 (0)