From bac338f80a4daad241c64d67a7ea5b64efd6ae5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Thu, 24 Mar 2022 14:44:03 +0000 Subject: [PATCH 01/13] first pass at decimal dates --- r/R/dplyr-funcs-datetime.R | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index c583aed5472..b7a95e15aa2 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -309,6 +309,31 @@ register_bindings_duration <- function() { build_expr("cast", x, options = cast_options(to_type = duration(unit = "s"))) }) + register_binding("decimal_date", function(date) { + y <- call_binding("year", date) + timezone <- call_binding("tz", date) + start <- call_binding("make_datetime", year = y, tz = timezone) + end <- call_binding("make_datetime", year = y + 1L, tz = timezone) + # maybe use yday here + sofar <- call_binding("difftime", date, start, units = "secs") + total <- call_binding("difftime", end, start, units = "secs") + y + call_binding("as.numeric", sofar) / call_binding("as.numeric", total) + }) + register_binding("date_decimal", function(decimal, tz = "UTC") { + y <- call_binding( + "cast", + decimal, + options = cast_options(to_type = int32(), safe = FALSE) + ) + + start <- call_binding("make_datetime", year = y, tz = tz) + end <- call_binding("make_datetime", year = y + 1, tz = tz) + + seconds <- call_binding("difftime", end, start, unit = "secs") + fraction <- decimal - y + end <- start + seconds * fraction + end + }) } binding_format_datetime <- function(x, format = "", tz = "", usetz = FALSE) { From 21dd80d448953c31ad51d6334c0c83ae6666f4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Thu, 24 Mar 2022 15:54:45 +0000 Subject: [PATCH 02/13] NEWS + testing df --- r/NEWS.md | 1 + r/tests/testthat/test-dplyr-funcs-datetime.R | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/r/NEWS.md b/r/NEWS.md index 0a7d30d2a37..e871cb9404d 100644 --- a/r/NEWS.md +++ b/r/NEWS.md @@ -23,6 +23,7 @@ * `lubridate`: * component extraction functions: `tz()` (timezone), `semester()` (semester), `dst()` (daylight savings time indicator), `date()` (extract date), `epiyear()` (epiyear), improvements to `month()`, which now works with integer inputs. * `make_date()` & `make_datetime()` + `ISOdatetime()` & `ISOdate()` to create date-times from numeric representations. + * `decimal_date()` and `date_decimal()` * date-time functionality: * `difftime` and `as.difftime()` * `as.Date()` to convert to date diff --git a/r/tests/testthat/test-dplyr-funcs-datetime.R b/r/tests/testthat/test-dplyr-funcs-datetime.R index 6df40505d1a..45382e720b6 100644 --- a/r/tests/testthat/test-dplyr-funcs-datetime.R +++ b/r/tests/testthat/test-dplyr-funcs-datetime.R @@ -1186,3 +1186,19 @@ test_that("as.difftime()", { collect() ) }) + +test_that("`decimal_date()` and `date_decimal()`", { + test_df <- tibble( + a = c(2007.38998954347, 1970.77732069883, 2020.96061799722, + 2009.43465948477, 1975.71251467871, NA), + b = as.POSIXct( + c("2007-05-23 08:18:30", "1970-10-11 17:19:45", "2020-12-17 14:04:06", + "2009-06-08 15:37:01", "1975-09-18 01:37:42", NA) + ), + c = c(1179908310.24298, 24513585.5584592, 1608213846.55522, + 1244475421.51183, 180236262.90795, NA) + ) + + test_df %>% + mutate(date_from_decimal_date = date_decimal(a)) +}) From 2ee535d16bec29fe6b1aff5bbd7dfe9e8d54b4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Fri, 25 Mar 2022 18:14:53 +0000 Subject: [PATCH 03/13] workaround for subtraction between date32 and timestamp --- r/R/dplyr-funcs-datetime.R | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index b7a95e15aa2..ea2bf536953 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -259,7 +259,7 @@ register_bindings_duration <- function() { if (!missing(tz)) { warn("`tz` argument is not supported in Arrow, so it will be ignored") } - +# browser() # cast to timestamp if time1 and time2 are not dates or timestamp expressions # (the subtraction of which would output a `duration`) if (!call_binding("is.instant", time1)) { @@ -270,6 +270,17 @@ register_bindings_duration <- function() { time2 <- build_expr("cast", time2, options = cast_options(to_type = timestamp(timezone = "UTC"))) } + # if time1 or time2 are timestamps they need to be in "us" + if (inherits(time1, "Expression") && + time1$type_id() %in% Type[c("TIMESTAMP")] && time1$type()$unit() != 2L) { + time1 <- build_expr("cast", time1, options = cast_options(to_type = timestamp("us"))) + } + + if (inherits(time2, "Expression") && + time2$type_id() %in% Type[c("TIMESTAMP")] && time2$type()$unit() != 2L) { + time2 <- build_expr("cast", time2, options = cast_options(to_type = timestamp("us"))) + } + # we need to go build the subtract expression instead of `time1 - time2` to # prevent complaints when we try to subtract an R object from an Expression subtract_output <- build_expr("-", time1, time2) @@ -310,17 +321,18 @@ register_bindings_duration <- function() { build_expr("cast", x, options = cast_options(to_type = duration(unit = "s"))) }) register_binding("decimal_date", function(date) { - y <- call_binding("year", date) - timezone <- call_binding("tz", date) - start <- call_binding("make_datetime", year = y, tz = timezone) - end <- call_binding("make_datetime", year = y + 1L, tz = timezone) + # browser() + y <- build_expr("year", date) + # timezone <- call_binding("tz", date) + start <- call_binding("make_datetime", year = y, tz = "UTC") + end <- call_binding("make_datetime", year = y + 1L, tz = "UTC") # maybe use yday here sofar <- call_binding("difftime", date, start, units = "secs") total <- call_binding("difftime", end, start, units = "secs") - y + call_binding("as.numeric", sofar) / call_binding("as.numeric", total) + y + sofar$cast(int64()) / total$cast(int64()) }) register_binding("date_decimal", function(decimal, tz = "UTC") { - y <- call_binding( + y <- build_expr( "cast", decimal, options = cast_options(to_type = int32(), safe = FALSE) @@ -329,11 +341,13 @@ register_bindings_duration <- function() { start <- call_binding("make_datetime", year = y, tz = tz) end <- call_binding("make_datetime", year = y + 1, tz = tz) - seconds <- call_binding("difftime", end, start, unit = "secs") + seconds <- call_binding("difftime", end, start, units = "secs") fraction <- decimal - y - end <- start + seconds * fraction + delta <- seconds$cast(int64()) * fraction + delta <- delta$cast(int64(), safe = FALSE) + end <- start + delta$cast(duration("s")) end - }) + }) } binding_format_datetime <- function(x, format = "", tz = "", usetz = FALSE) { From babb0fe751d6a8332f7d115546c2282285936eba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Fri, 25 Mar 2022 18:15:12 +0000 Subject: [PATCH 04/13] unit tests --- r/tests/testthat/test-dplyr-funcs-datetime.R | 29 ++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/r/tests/testthat/test-dplyr-funcs-datetime.R b/r/tests/testthat/test-dplyr-funcs-datetime.R index 45382e720b6..a5fb1f6f75a 100644 --- a/r/tests/testthat/test-dplyr-funcs-datetime.R +++ b/r/tests/testthat/test-dplyr-funcs-datetime.R @@ -1103,6 +1103,17 @@ test_that("difftime works correctly", { test_df_with_tz ) + test_df_with_tz %>% + arrow_table() %>% + mutate( + secs2 = difftime( + as.POSIXct("2022-03-07", tz = "Europe/Bucharest"), + time1, + units = "secs" + ) + ) %>% + collect() + compare_dplyr_binding( .input %>% mutate( @@ -1193,12 +1204,26 @@ test_that("`decimal_date()` and `date_decimal()`", { 2009.43465948477, 1975.71251467871, NA), b = as.POSIXct( c("2007-05-23 08:18:30", "1970-10-11 17:19:45", "2020-12-17 14:04:06", - "2009-06-08 15:37:01", "1975-09-18 01:37:42", NA) + "2009-06-08 15:37:01", "1975-09-18 01:37:42", NA) ), c = c(1179908310.24298, 24513585.5584592, 1608213846.55522, 1244475421.51183, 180236262.90795, NA) ) test_df %>% - mutate(date_from_decimal_date = date_decimal(a)) + # arrow_table() %>% + mutate(decimal_date_from_r_obj = decimal_date(ymd("2022-03-25"))) %>% + collect() + + compare_dplyr_binding( + .input %>% + mutate(decimal_date_from_date = decimal_date(b), + decimal_date_from_r_obj = decimal_date(ymd("2022-03-25"))) %>% + collect(), + test_df, + ignore_attr = TRUE, + # in some cases there are small differences in the decimal dates + tolerance = 0.0001 + ) + }) From c146ef37ba8d35fd1aff61d8dccfafd26a74dbad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Mon, 28 Mar 2022 17:45:20 +0100 Subject: [PATCH 05/13] unit tests --- r/tests/testthat/test-dplyr-funcs-datetime.R | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/r/tests/testthat/test-dplyr-funcs-datetime.R b/r/tests/testthat/test-dplyr-funcs-datetime.R index a5fb1f6f75a..27a81c6d73d 100644 --- a/r/tests/testthat/test-dplyr-funcs-datetime.R +++ b/r/tests/testthat/test-dplyr-funcs-datetime.R @@ -1205,25 +1205,18 @@ test_that("`decimal_date()` and `date_decimal()`", { b = as.POSIXct( c("2007-05-23 08:18:30", "1970-10-11 17:19:45", "2020-12-17 14:04:06", "2009-06-08 15:37:01", "1975-09-18 01:37:42", NA) - ), - c = c(1179908310.24298, 24513585.5584592, 1608213846.55522, - 1244475421.51183, 180236262.90795, NA) + ) ) - test_df %>% - # arrow_table() %>% - mutate(decimal_date_from_r_obj = decimal_date(ymd("2022-03-25"))) %>% - collect() - compare_dplyr_binding( .input %>% mutate(decimal_date_from_date = decimal_date(b), - decimal_date_from_r_obj = decimal_date(ymd("2022-03-25"))) %>% + decimal_date_from_r_obj = decimal_date(ymd("2022-03-25")), + date_from_decimal = date_decimal(a), + date_from_decimal_r_obj = date_decimal(2022.178)) %>% collect(), test_df, - ignore_attr = TRUE, - # in some cases there are small differences in the decimal dates - tolerance = 0.0001 + ignore_attr = "tzone" ) }) From da3a0707c11caf96875f4f6800b1a0f319980c21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Mon, 28 Mar 2022 17:46:55 +0100 Subject: [PATCH 06/13] :facepalm: --- r/R/dplyr-funcs-datetime.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index ea2bf536953..a115fc48799 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -259,7 +259,7 @@ register_bindings_duration <- function() { if (!missing(tz)) { warn("`tz` argument is not supported in Arrow, so it will be ignored") } -# browser() + # cast to timestamp if time1 and time2 are not dates or timestamp expressions # (the subtraction of which would output a `duration`) if (!call_binding("is.instant", time1)) { From 99f030be69824fc35e02e9e40aded5180d6da217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Mon, 28 Mar 2022 17:48:27 +0100 Subject: [PATCH 07/13] improved comment --- r/R/dplyr-funcs-datetime.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index a115fc48799..0cbbf461981 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -270,7 +270,8 @@ register_bindings_duration <- function() { time2 <- build_expr("cast", time2, options = cast_options(to_type = timestamp(timezone = "UTC"))) } - # if time1 or time2 are timestamps they need to be in "us" + # if time1 or time2 are timestamps they cannot be expressed in "s" /seconds + # otherwise they cannot be added subtracted with durations if (inherits(time1, "Expression") && time1$type_id() %in% Type[c("TIMESTAMP")] && time1$type()$unit() != 2L) { time1 <- build_expr("cast", time1, options = cast_options(to_type = timestamp("us"))) From b58aebf838c274ab3a2731caab455d90f68cc556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Mon, 28 Mar 2022 18:06:01 +0100 Subject: [PATCH 08/13] removed extra empty row --- r/tests/testthat/test-dplyr-funcs-datetime.R | 1 - 1 file changed, 1 deletion(-) diff --git a/r/tests/testthat/test-dplyr-funcs-datetime.R b/r/tests/testthat/test-dplyr-funcs-datetime.R index 27a81c6d73d..fba9ceef6c3 100644 --- a/r/tests/testthat/test-dplyr-funcs-datetime.R +++ b/r/tests/testthat/test-dplyr-funcs-datetime.R @@ -1218,5 +1218,4 @@ test_that("`decimal_date()` and `date_decimal()`", { test_df, ignore_attr = "tzone" ) - }) From 83fbde66b9928c4bea36959b20693f650dc6c487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Tue, 29 Mar 2022 12:44:36 +0100 Subject: [PATCH 09/13] cleanup + more test cases --- r/tests/testthat/test-dplyr-funcs-datetime.R | 28 +++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/r/tests/testthat/test-dplyr-funcs-datetime.R b/r/tests/testthat/test-dplyr-funcs-datetime.R index fba9ceef6c3..2c819b3014c 100644 --- a/r/tests/testthat/test-dplyr-funcs-datetime.R +++ b/r/tests/testthat/test-dplyr-funcs-datetime.R @@ -1103,22 +1103,11 @@ test_that("difftime works correctly", { test_df_with_tz ) - test_df_with_tz %>% - arrow_table() %>% - mutate( - secs2 = difftime( - as.POSIXct("2022-03-07", tz = "Europe/Bucharest"), - time1, - units = "secs" - ) - ) %>% - collect() - compare_dplyr_binding( .input %>% mutate( secs2 = difftime( - as.POSIXct("2022-03-07", tz = "Europe/Bucharest"), + as.POSIXct("2022-03-07", tz = "Pacific/Marquesas"), time1, units = "secs" ) @@ -1205,15 +1194,22 @@ test_that("`decimal_date()` and `date_decimal()`", { b = as.POSIXct( c("2007-05-23 08:18:30", "1970-10-11 17:19:45", "2020-12-17 14:04:06", "2009-06-08 15:37:01", "1975-09-18 01:37:42", NA) + ), + c = as.Date( + c("2007-05-23", "1970-10-11", "2020-12-17", "2009-06-08", "1975-09-18", NA) ) ) compare_dplyr_binding( .input %>% - mutate(decimal_date_from_date = decimal_date(b), - decimal_date_from_r_obj = decimal_date(ymd("2022-03-25")), - date_from_decimal = date_decimal(a), - date_from_decimal_r_obj = date_decimal(2022.178)) %>% + mutate( + decimal_date_from_POSIXct = decimal_date(b), + decimal_date_from_r_POSIXct_obj = decimal_date(as.POSIXct("2022-03-25 15:37:01")), + decimal_date_from_r_date_obj = decimal_date(ymd("2022-03-25")), + decimal_date_from_date = decimal_date(c), + date_from_decimal = date_decimal(a), + date_from_decimal_r_obj = date_decimal(2022.178) + ) %>% collect(), test_df, ignore_attr = "tzone" From 8bbe52f4a9f63dc45aac62dfda4adcbfc8a9590a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Tue, 29 Mar 2022 12:45:17 +0100 Subject: [PATCH 10/13] `floor` instead of `safe = FALSE` casting + simplified implementation --- r/R/dplyr-funcs-datetime.R | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index 0cbbf461981..ff76994ad14 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -322,32 +322,32 @@ register_bindings_duration <- function() { build_expr("cast", x, options = cast_options(to_type = duration(unit = "s"))) }) register_binding("decimal_date", function(date) { - # browser() y <- build_expr("year", date) - # timezone <- call_binding("tz", date) start <- call_binding("make_datetime", year = y, tz = "UTC") - end <- call_binding("make_datetime", year = y + 1L, tz = "UTC") - # maybe use yday here sofar <- call_binding("difftime", date, start, units = "secs") - total <- call_binding("difftime", end, start, units = "secs") - y + sofar$cast(int64()) / total$cast(int64()) + total <- call_binding( + "if_else", + build_expr("is_leap_year", date), + call_binding("as.integer64", 31622400L), # number of seconds in a leap year (366 days) + call_binding("as.integer64", 31536000L) # number of seconds in a regular year (365 days) + ) + y + sofar$cast(int64()) / total }) register_binding("date_decimal", function(decimal, tz = "UTC") { - y <- build_expr( - "cast", - decimal, - options = cast_options(to_type = int32(), safe = FALSE) - ) + y <- build_expr("floor", decimal) start <- call_binding("make_datetime", year = y, tz = tz) - end <- call_binding("make_datetime", year = y + 1, tz = tz) + seconds <- call_binding( + "if_else", + build_expr("is_leap_year", start), + call_binding("as.integer64", 31622400L), # number of seconds in a leap year (366 days) + call_binding("as.integer64", 31536000L) # number of seconds in a regular year (365 days) + ) - seconds <- call_binding("difftime", end, start, units = "secs") fraction <- decimal - y - delta <- seconds$cast(int64()) * fraction - delta <- delta$cast(int64(), safe = FALSE) - end <- start + delta$cast(duration("s")) - end + delta <- build_expr("floor", seconds * fraction) + delta <- delta$cast(int64()) + start + delta$cast(duration("s")) }) } From 6f0ed8dde3c7243c97c442f610b3c200819be20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Tue, 29 Mar 2022 13:45:25 +0100 Subject: [PATCH 11/13] added reference to follow-up ticket --- r/R/dplyr-funcs-datetime.R | 2 ++ 1 file changed, 2 insertions(+) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index ff76994ad14..184d4a5b595 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -272,6 +272,8 @@ register_bindings_duration <- function() { # if time1 or time2 are timestamps they cannot be expressed in "s" /seconds # otherwise they cannot be added subtracted with durations + # TODO delete the casting to "us" once + # https://issues.apache.org/jira/browse/ARROW-16060 is solved if (inherits(time1, "Expression") && time1$type_id() %in% Type[c("TIMESTAMP")] && time1$type()$unit() != 2L) { time1 <- build_expr("cast", time1, options = cast_options(to_type = timestamp("us"))) From ae3114e972ed9e394d61155d853c8abf13813d26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Tue, 29 Mar 2022 18:15:15 +0100 Subject: [PATCH 12/13] create an `Expression$scalar()` instead of casting one --- r/R/dplyr-funcs-datetime.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index 184d4a5b595..f585c984c9a 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -330,8 +330,8 @@ register_bindings_duration <- function() { total <- call_binding( "if_else", build_expr("is_leap_year", date), - call_binding("as.integer64", 31622400L), # number of seconds in a leap year (366 days) - call_binding("as.integer64", 31536000L) # number of seconds in a regular year (365 days) + Expression$scalar(31622400L), # number of seconds in a leap year (366 days) + Expression$scalar(31536000L) # number of seconds in a regular year (365 days) ) y + sofar$cast(int64()) / total }) @@ -342,8 +342,8 @@ register_bindings_duration <- function() { seconds <- call_binding( "if_else", build_expr("is_leap_year", start), - call_binding("as.integer64", 31622400L), # number of seconds in a leap year (366 days) - call_binding("as.integer64", 31536000L) # number of seconds in a regular year (365 days) + Expression$scalar(31622400L), # number of seconds in a leap year (366 days) + Expression$scalar(31536000L) # number of seconds in a regular year (365 days) ) fraction <- decimal - y From 63445b7b406b092a624cf0996981d8c1e6ea3a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Drago=C8=99=20Moldovan-Gr=C3=BCnfeld?= Date: Mon, 4 Apr 2022 21:10:49 +0300 Subject: [PATCH 13/13] news update + style --- r/NEWS.md | 8 ++++---- r/R/dplyr-funcs-datetime.R | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/r/NEWS.md b/r/NEWS.md index e871cb9404d..1a1f198e0f3 100644 --- a/r/NEWS.md +++ b/r/NEWS.md @@ -22,11 +22,11 @@ * `read_csv_arrow()`'s readr-style type `T` is now mapped to `timestamp(unit = "ns")` instead of `timestamp(unit = "s")`. * `lubridate`: * component extraction functions: `tz()` (timezone), `semester()` (semester), `dst()` (daylight savings time indicator), `date()` (extract date), `epiyear()` (epiyear), improvements to `month()`, which now works with integer inputs. - * `make_date()` & `make_datetime()` + `ISOdatetime()` & `ISOdate()` to create date-times from numeric representations. - * `decimal_date()` and `date_decimal()` + * Added `make_date()` & `make_datetime()` + `ISOdatetime()` & `ISOdate()` to create date-times from numeric representations. + * Added `decimal_date()` and `date_decimal()` * date-time functionality: - * `difftime` and `as.difftime()` - * `as.Date()` to convert to date + * Added `difftime` and `as.difftime()` + * Added `as.Date()` to convert to date # arrow 7.0.0 diff --git a/r/R/dplyr-funcs-datetime.R b/r/R/dplyr-funcs-datetime.R index f585c984c9a..586c9d6d3f5 100644 --- a/r/R/dplyr-funcs-datetime.R +++ b/r/R/dplyr-funcs-datetime.R @@ -332,7 +332,7 @@ register_bindings_duration <- function() { build_expr("is_leap_year", date), Expression$scalar(31622400L), # number of seconds in a leap year (366 days) Expression$scalar(31536000L) # number of seconds in a regular year (365 days) - ) + ) y + sofar$cast(int64()) / total }) register_binding("date_decimal", function(decimal, tz = "UTC") {