Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ S3method(vec_proxy_order,array)
S3method(vec_proxy_order,default)
S3method(vec_proxy_order,list)
S3method(vec_proxy_order,raw)
S3method(vec_ptype,POSIXlt)
S3method(vec_ptype2,AsIs)
S3method(vec_ptype2,Date)
S3method(vec_ptype2,POSIXct)
Expand Down
16 changes: 16 additions & 0 deletions R/type-date-time.R
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,22 @@ vec_ptype_abbr.difftime <- function(x, ...) {
"drtn"
}

# Ptype -------------------------------------------------------------------

#' @export
vec_ptype.POSIXlt <- function(x, ...) {
# `vec_ptype2()` pushes towards `POSIXct`. In theory, maybe `vec_ptype()`
# should as well so that `vec_c(<POSIXlt>)` and `vec_c(<POSIXlt>, <POSIXlt>)`
# are consistent and both return `POSIXct`. In practice this broke a number of
# packages (datetimeoffset, slider, nanoarrow), and also generally means that
# you wouldn't be able to provide a `POSIXlt` as a `ptype` argument to
# anything and expect it to return a `POSIXlt` as output. So we've decided to
# just leave this inconsistency. Getting `POSIXlt` attributes exactly right
# is very tricky, and very R version dependent, so we just consistency align
# with `[` here and in tests.
x[0]
}

# Coerce ------------------------------------------------------------------

#' @rdname new_date
Expand Down
34 changes: 33 additions & 1 deletion tests/testthat/test-type-date-time.R
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,18 @@ test_that("tz comes from first non-empty", {
expect_identical(vec_ptype2(z, y), z[0])
})

test_that("POSIXlt always steered towards POSIXct", {
test_that("POSIXlt remains POSIXlt in vec_ptype()", {
# See `vec_ptype.POSIXlt()` for details
x <- as.POSIXlt("2020-01-01", tz = "UTC")
exp <- x[0]
expect_identical(vec_ptype(x), exp)

x <- as.POSIXlt("2020-01-01", tz = "America/New_York")
exp <- x[0]
expect_identical(vec_ptype(x), exp)
})

test_that("POSIXlt always steered towards POSIXct in vec_ptype2()", {
dtc <- as.POSIXct("2020-01-01", tz = "UTC")
dtl <- as.POSIXlt("2020-01-01", tz = "UTC")

Expand Down Expand Up @@ -192,6 +203,27 @@ test_that("vec_ptype2() standardizes duration storage type to double", {
expect_identical(vec_ptype2(x, x), expect)
})

test_that("vec_ptype_common() gives expected results with <POSIXlt>", {
# See `vec_ptype.POSIXlt()` for details
x <- as.POSIXlt("2020-01-01", tz = "UTC")

# `vec_ptype(x)` returns `<POSIXlt>`
exp <- x[0]
expect_identical(vec_ptype_common(x), exp)
expect_identical(vec_ptype_common(.ptype = x), exp)

# `vec_ptype2(x, x)` returns `<POSIXct>`
exp <- new_datetime(tzone = "UTC")
expect_identical(vec_ptype_common(x, x), exp)

# With <unspecified> input, still uses `vec_ptype(x)`, so returns `<POSIXlt>`
exp <- x[0]
expect_identical(vec_ptype_common(x, NA), exp)
expect_identical(vec_ptype_common(NA, x), exp)
expect_identical(vec_ptype_common(x, NULL), exp)
expect_identical(vec_ptype_common(NULL, x), exp)
})

# cast: dates ---------------------------------------------------------------

test_that("safe casts work as expected", {
Expand Down