diff --git a/NAMESPACE b/NAMESPACE index e97caf01..0fe0214c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand S3method(as_fmt_char,"NULL") +S3method(as_fmt_char,POSIXt) S3method(as_fmt_char,character) S3method(as_fmt_char,default) S3method(as_fmt_char,factor) diff --git a/NEWS.md b/NEWS.md index e40a295c..8ea698c2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,6 +9,7 @@ Development version - Added check to ensure that the column ordering is the same (#32) - Added more informative error messaging if a specified key is missing from the base or comparison dataset (#113) - Added check for differences in classes between the base and comparison datasets (#42) +- Updated character formatting of datetimes to show time zone to avoid misleading/confusing comparisons (#121) # diffdf 1.0.4 diff --git a/R/ascii_tables.R b/R/ascii_tables.R index b4fb15b8..4a83103c 100644 --- a/R/ascii_tables.R +++ b/R/ascii_tables.R @@ -220,6 +220,13 @@ as_fmt_char.default <- function(x, ...) { } +#' @rdname as_fmt_char +#' @export +as_fmt_char.POSIXt <- function(x, ...) { + format(x, "%Y-%m-%d %H:%M:%S %Z") +} + + #' get_table #' #' Generate nice looking table from a data frame diff --git a/inst/WORDLIST b/inst/WORDLIST index 15ad8c17..9c828688 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -5,3 +5,5 @@ Comparator tibble int64 int +datetimes +datetime diff --git a/man/as_fmt_char.Rd b/man/as_fmt_char.Rd index 4af5b36f..fcea7650 100644 --- a/man/as_fmt_char.Rd +++ b/man/as_fmt_char.Rd @@ -8,6 +8,7 @@ \alias{as_fmt_char.factor} \alias{as_fmt_char.character} \alias{as_fmt_char.default} +\alias{as_fmt_char.POSIXt} \title{Format vector to printable string} \usage{ as_fmt_char(x, ...) @@ -23,6 +24,8 @@ as_fmt_char(x, ...) \method{as_fmt_char}{character}(x, add_quotes = TRUE, crop_at = 30, ...) \method{as_fmt_char}{default}(x, ...) + +\method{as_fmt_char}{POSIXt}(x, ...) } \arguments{ \item{x}{(\code{vector}) \cr vector to be converted to character} diff --git a/tests/testthat/_snaps/miscellaneous.md b/tests/testthat/_snaps/miscellaneous.md index fd76dd65..d443a7c5 100644 --- a/tests/testthat/_snaps/miscellaneous.md +++ b/tests/testthat/_snaps/miscellaneous.md @@ -210,28 +210,98 @@ Code cat(as_ascii_table(TDAT)) Output - ==================================================================================================================================== - ID GROUP1 GROUP2 INTEGER BINARY DATE DATETIME CONTINUOUS CATEGORICAL LOGICAL CHARACTER - ------------------------------------------------------------------------------------------------------------------------------------ - 1 1 1 38 M 1972-04-20 2004-06-05 21:11:45.354559 15.65720 C FALSE knlCkyGngudhQDG7c1S - 2 1 2 42 M 1965-04-19 2008-12-15 08:20:36.429131 39.82418 C FALSE WS79tq36Lb39x - 3 1 3 46 F 2001-02-12 2001-10-24 09:56:57.202774 49.87364 C TRUE GCrvtl0QiH - 4 1 4 42 F 2001-05-22 2012-06-28 17:50:21.938828 29.06446 A TRUE ICSsDEAqiAJq2 - 5 1 5 41 F 1998-04-27 2003-04-28 13:32:27.331497 26.15303 A FALSE HpCkoxPvlWBxcaN - 6 1 6 42 M 2034-09-01 2007-06-07 18:41:57.268269 28.82976 C FALSE bn3I34EvoYbJDScFQ - 7 1 7 42 F 2048-12-06 1999-07-09 22:03:19.971158 16.29289 C TRUE 6rdaFqOV2mTU - 8 1 8 44 M 2006-08-11 2002-07-05 12:33:20.318665 31.09172 A FALSE xPRLB6RO0APlL - 9 1 9 38 F 2013-03-30 1978-12-14 06:32:36.057939 31.74536 B TRUE wVl - 10 1 10 42 F 2006-09-21 1992-06-02 14:06:25.088742 34.14493 A FALSE DJoblLpQ20S2i - 11 2 1 36 F 2008-02-17 2001-01-07 07:50:46.023329 40.03511 B TRUE EAS1pDstlU2 - 12 2 2 41 M 1992-03-26 2005-10-17 21:24:38.423865 17.58570 B TRUE hjpkwY79ou0n - 13 2 3 37 M 1990-02-22 1997-11-10 15:55:11.632764 32.73208 A FALSE lhIxIjBK - 14 2 4 40 F 2013-06-05 2001-10-09 14:26:14.526603 30.41580 B FALSE 7MmcGgpNQbTCB0 - 15 2 5 45 M 1994-01-04 1995-10-26 12:40:41.719801 36.72617 C FALSE 5kPDzTjL5o - 16 2 6 46 F 1986-05-08 2000-04-29 11:03:21.562663 15.46634 A TRUE cyRkPs5IdBO2 - 17 2 7 39 M 1973-11-13 1996-07-13 23:45:42.755799 20.73752 C TRUE Xo4vqSewCJc - 18 2 8 36 F 2013-02-16 2007-09-09 03:46:54.120426 30.00495 A TRUE 2LZ4RfA - 19 2 9 33 M 2037-06-17 2006-03-30 05:40:18.051513 39.57820 A FALSE RoF1sY15ZSwb9o4U - 20 2 10 41 M 2011-10-19 1999-02-13 14:28:10.86756 21.22740 C FALSE ULGFHE1 - ------------------------------------------------------------------------------------------------------------------------------------ + ================================================================================================================================= + ID GROUP1 GROUP2 INTEGER BINARY DATE DATETIME CONTINUOUS CATEGORICAL LOGICAL CHARACTER + --------------------------------------------------------------------------------------------------------------------------------- + 1 1 1 38 M 1972-04-20 2004-06-05 21:11:45 UTC 15.65720 C FALSE knlCkyGngudhQDG7c1S + 2 1 2 42 M 1965-04-19 2008-12-15 08:20:36 UTC 39.82418 C FALSE WS79tq36Lb39x + 3 1 3 46 F 2001-02-12 2001-10-24 09:56:57 UTC 49.87364 C TRUE GCrvtl0QiH + 4 1 4 42 F 2001-05-22 2012-06-28 17:50:21 UTC 29.06446 A TRUE ICSsDEAqiAJq2 + 5 1 5 41 F 1998-04-27 2003-04-28 13:32:27 UTC 26.15303 A FALSE HpCkoxPvlWBxcaN + 6 1 6 42 M 2034-09-01 2007-06-07 18:41:57 UTC 28.82976 C FALSE bn3I34EvoYbJDScFQ + 7 1 7 42 F 2048-12-06 1999-07-09 22:03:19 UTC 16.29289 C TRUE 6rdaFqOV2mTU + 8 1 8 44 M 2006-08-11 2002-07-05 12:33:20 UTC 31.09172 A FALSE xPRLB6RO0APlL + 9 1 9 38 F 2013-03-30 1978-12-14 06:32:36 UTC 31.74536 B TRUE wVl + 10 1 10 42 F 2006-09-21 1992-06-02 14:06:25 UTC 34.14493 A FALSE DJoblLpQ20S2i + 11 2 1 36 F 2008-02-17 2001-01-07 07:50:46 UTC 40.03511 B TRUE EAS1pDstlU2 + 12 2 2 41 M 1992-03-26 2005-10-17 21:24:38 UTC 17.58570 B TRUE hjpkwY79ou0n + 13 2 3 37 M 1990-02-22 1997-11-10 15:55:11 UTC 32.73208 A FALSE lhIxIjBK + 14 2 4 40 F 2013-06-05 2001-10-09 14:26:14 UTC 30.41580 B FALSE 7MmcGgpNQbTCB0 + 15 2 5 45 M 1994-01-04 1995-10-26 12:40:41 UTC 36.72617 C FALSE 5kPDzTjL5o + 16 2 6 46 F 1986-05-08 2000-04-29 11:03:21 UTC 15.46634 A TRUE cyRkPs5IdBO2 + 17 2 7 39 M 1973-11-13 1996-07-13 23:45:42 UTC 20.73752 C TRUE Xo4vqSewCJc + 18 2 8 36 F 2013-02-16 2007-09-09 03:46:54 UTC 30.00495 A TRUE 2LZ4RfA + 19 2 9 33 M 2037-06-17 2006-03-30 05:40:18 UTC 39.57820 A FALSE RoF1sY15ZSwb9o4U + 20 2 10 41 M 2011-10-19 1999-02-13 14:28:10 UTC 21.22740 C FALSE ULGFHE1 + --------------------------------------------------------------------------------------------------------------------------------- + +# datetimes compare as expected + + Code + print(res) + Output + Differences found between the objects! + + Summary of BASE and COMPARE + ================================================================== + PROPERTY BASE COMP + ------------------------------------------------------------------ + Name d1 d2 + Class "tbl_df, tbl, data.frame" "tbl_df, tbl, data.frame" + Rows(#) 2 2 + Columns(#) 2 2 + ------------------------------------------------------------------ + + + There are columns in BASE and COMPARE with differing attributes !! + =============================================== + VARIABLE ATTR_NAME VALUES.BASE VALUES.COMP + ----------------------------------------------- + dt1 tzone EST CET + ----------------------------------------------- + + + Not all Values Compared Equal + ============================= + Variable No of Differences + ----------------------------- + dt1 2 + ----------------------------- + + + ================================================================ + VARIABLE id BASE COMPARE + ---------------------------------------------------------------- + dt1 1 2024-01-10 01:02:03 EST 2024-01-10 01:02:03 CET + dt1 2 2024-01-24 14:12:49 EST 2024-01-24 14:12:49 CET + ---------------------------------------------------------------- + + + +--- + + Code + print(res) + Output + Differences found between the objects! + + Summary of BASE and COMPARE + ================================================================== + PROPERTY BASE COMP + ------------------------------------------------------------------ + Name d1 d2 + Class "tbl_df, tbl, data.frame" "tbl_df, tbl, data.frame" + Rows(#) 2 2 + Columns(#) 2 2 + ------------------------------------------------------------------ + + + There are columns in BASE and COMPARE with differing attributes !! + =============================================== + VARIABLE ATTR_NAME VALUES.BASE VALUES.COMP + ----------------------------------------------- + dt1 tzone EST CET + ----------------------------------------------- + + diff --git a/tests/testthat/test-miscellaneous.R b/tests/testthat/test-miscellaneous.R index 44efcb8e..b21692a6 100644 --- a/tests/testthat/test-miscellaneous.R +++ b/tests/testthat/test-miscellaneous.R @@ -168,11 +168,14 @@ test_that("Format Char works on standard data types", { ) expect_equal( - as_fmt_char(c( - lubridate::ymd_hms("2023-07-26 12:00:00", tz = "CET"), - lubridate::ymd_hms("1888-01-29 15:45:30", tz = "CET") + as_fmt_char(lubridate::ymd_hms( + c( + "2023-01-01 14:12:12", + "1888-01-05 15:45:30" + ), + tz = "CET" )), - c("2023-07-26 12:00:00", "1888-01-29 15:45:30") + c("2023-01-01 14:12:12 CET", "1888-01-05 15:45:30 CET") ) x <- c(1, 2, 3, 4) @@ -199,3 +202,53 @@ test_that("Format Char works on standard data types", { test_that("ascii_table can handle all standard datatypes", { expect_snapshot(as_ascii_table(TDAT) |> cat()) }) + + +test_that("datetimes compare as expected", { + + # Same character values but different underlying numerics + d1 <- tibble( + id = c(1, 2), + dt1 = lubridate::ymd_hms( + "2024-01-10 01-02-03", + "2024-01-24 14-12-49", + tz = "EST" + ) + ) + d2 <- tibble( + id = c(1, 2), + dt1 = lubridate::ymd_hms( + "2024-01-10 01-02-03", + "2024-01-24 14-12-49", + tz = "CET" + ) + ) + expect_warning( + res <- diffdf(d1, d2, "id"), + regexp = "differing attributes.*Not all Values Compared Equal" + ) + expect_snapshot( + print(res) + ) + + + + # Same underlying numerics but different character values + d1 <- tibble( + id = c(1, 2), + dt1 = lubridate::ymd_hms( + "2024-01-10 01-02-03", + "2024-01-24 14-12-49", + tz = "EST" + ) + ) + d2 <- d1 + d2$dt1 <- lubridate::with_tz(d2$dt1, tzone = "CET") + expect_warning( + res <- diffdf(d1, d2, "id"), + regexp = "differing attributes[ !]*$" + ) + expect_snapshot( + print(res) + ) +})