diff --git a/R/assign_date.R b/R/assign_date.R index 954f6cf..394885f 100644 --- a/R/assign_date.R +++ b/R/assign_date.R @@ -5,7 +5,7 @@ #' `r lifecycle::badge("maturing")` #' #' `assign_date()` assign dates to two sequential hours. It can facilitate -#' time arithmetic by locating time values without date reference on a +#' time arithmetic by locating time values without a date reference on a #' timeline. #' #' @details @@ -44,52 +44,35 @@ #' hours, i.e., `start` and `end` distance themselves by one day. #' * `ambiguity = NA`: to disregard these cases, assigning `NA` as value. #' -#' ## `return` argument +#' ## Base date and timezone #' -#' `assign_date()` can return different outputs: +#' `assign_date()` uses the +#' [Unix epoch](https://en.wikipedia.org/wiki/Unix_time) (1970-01-01) date as +#' the start date for creating intervals. #' -#' * `return = "Interval"`: returns a `start`--`end` `Interval` object. -#' * `return = "list"`: returns a `list` object with two named elements -#' corresponding to `start` and `end` output. -#' * `return = "start"`: returns only the `start` output. -#' * `return = "end"`: returns only the `end` output. -#' -#' ## `start_name` and `end_name` arguments -#' -#' These arguments serve to instruct `assign_date()` on how to name the -#' list elements when `return = "list"`. By default, the function will name -#' these elements with the names of the variables assigned to `start` and `end` -#' arguments. -#' -#' If the number of characters (`nchar()`) of `start_name` or `end_name` are -#' equal or greater than 30, `assign_date()` will name the list elements as -#' `"start"` and `"end"`. +#' The output will always have `"UTC"` set as timezone. Learn more about +#' time zones in [base::timezone]. #' #' ## `POSIXt` objects #' -#' `POSIXt` values passed as argument to `start` or `end` will be stripped of +#' `POSIXt` objects passed as argument to `start` or `end` will be stripped of #' their dates. Only the time will be considered. #' +#' Both `POSIXct` and `POSIXlt` are objects that inherits the class `POSIXt`. +#' Learn more about it in [base::DateTimeClasses]. +#' #' ## `NA` values #' -#' `assign_date()` will return `NA` if `start` or `end` are `NA`. +#' `assign_date()` will return an `Interval` `NA`-`NA` if `start` or `end` are +#' `NA`. #' #' @param start,end A `hms` or `POSIXt` object indicating the start or end #' hour. #' @param ambiguity (optional) a `numeric` or `NA` value to instruct #' `assign_date()` on how to deal with ambiguities (see Details) (default: #' `0`). -#' @param return (optional) a string indicating the type of the output (see -#' Details) (default: `"Interval"`). -#' @param start_name,end_name (optional) a string indicating a name associated -#' with the `start` and `end` argument. #' -#' @return -#' -#' * If `return = "Interval"`, a `start`--`end` `Interval` object. -#' * If `return = "list"`, a named list with `start` and `end` as elements. -#' * If `return = "start`, only the `start` output. -#' * If `return = "end"`, only the `end` output. +#' @return A `start`--`end` `Interval` object. #' #' @family utility functions #' @export @@ -120,58 +103,21 @@ #' #> [1] 1970-01-01 09:45:00 UTC--1970-01-01 21:15:00 UTC # Expected #' #> [2] 1970-01-01 20:30:00 UTC--1970-01-02 04:30:00 UTC # Expected #' -#' ## To return `start` and `end` as interval (default) -#' -#' start <- hms::parse_hm("12:34") -#' end <- hms::parse_hm("01:25") -#' assign_date(start, end) -#' #> [1] 1970-01-01 12:34:00 UTC--1970-01-02 01:25:00 UTC # Expected -#' -#' ## To return `start` and `end` as list -#' -#' start <- hms::parse_hm("22:15") -#' end <- hms::parse_hm("00:01") -#' assign_date(start, end, return = "list") -#' #> $start # Expected -#' #> [1] "1970-01-01 22:15:00 UTC" # Expected -#' #> # Expected -#' #> $end # Expected -#' #> [1] "1970-01-02 00:01:00 UTC" # Expected -#' -#' ## To return only `start` or `end` -#' -#' start <- lubridate::parse_date_time("01:10:00", "HMS") -#' end <- lubridate::parse_date_time("11:45:00", "HMS") -#' assign_date(start, end, return = "start") -#' #> [1] "1970-01-01 01:10:00 UTC" # Expected -#' assign_date(start, end, return = "end") -#' #> [1] "1970-01-01 11:45:00 UTC" # Expected -#' #' ## To assign a 24 hours interval to ambiguities #' #' start <- lubridate::as_datetime("1985-01-15 12:00:00") #' end <- lubridate::as_datetime("2020-09-10 12:00:00") #' assign_date(start, end, ambiguity = 24) #' #> [1] 1970-01-01 12:00:00 UTC--1970-01-02 12:00:00 UTC # Expected -assign_date <- function(start, end, return = "Interval", ambiguity = 0, - start_name = deparse(substitute(start)), - end_name = deparse(substitute(end))) { - checkmate::assert_multi_class(start, c("hms", "POSIXct", "POSIXlt")) - checkmate::assert_multi_class(end, c("hms", "POSIXct", "POSIXlt")) +assign_date <- function(start, end, ambiguity = 0) { + checkmate::assert_multi_class(start, c("hms", "POSIXt")) + checkmate::assert_multi_class(end, c("hms", "POSIXt")) assert_identical(start, end, type = "length") checkmate::assert_numeric(as.numeric(hms::as_hms(start)), lower = 0, upper = 86400) checkmate::assert_numeric(as.numeric(hms::as_hms(end)), lower = 0, upper = 86400) - checkmate::assert_choice(tolower(return), - c("list", "interval", "start", "end")) checkmate::assert_choice(ambiguity, c(0, 24 , NA)) - checkmate::assert_string(start_name) - checkmate::assert_string(end_name) - - return <- tolower(return) - start_name <- start_name[1] - end_name <- end_name[1] start <- flat_posixt(convert(start, "posixct", quiet = TRUE)) end <- flat_posixt(convert(end, "posixct", quiet = TRUE)) @@ -184,20 +130,5 @@ assign_date <- function(start, end, return = "Interval", ambiguity = 0, TRUE ~ lubridate::as.interval(lubridate::hours(ambiguity), start) ) - if (return == "interval") { - out - } else if (return == "start") { - lubridate::int_start(out) - } else if (return == "end") { - lubridate::int_end(out) - } else { - out <- list(start = lubridate::int_start(out), - end = lubridate::int_end(out)) - - if (nchar(start_name) < 30 && nchar(end_name) < 30) { - names(out) <- c(start_name, end_name) - } - - out - } + out } diff --git a/man/assign_date.Rd b/man/assign_date.Rd index dd7bd95..798fe13 100644 --- a/man/assign_date.Rd +++ b/man/assign_date.Rd @@ -4,42 +4,24 @@ \alias{assign_date} \title{Assign dates to two sequential hours} \usage{ -assign_date( - start, - end, - return = "Interval", - ambiguity = 0, - start_name = deparse(substitute(start)), - end_name = deparse(substitute(end)) -) +assign_date(start, end, ambiguity = 0) } \arguments{ \item{start, end}{A \code{hms} or \code{POSIXt} object indicating the start or end hour.} -\item{return}{(optional) a string indicating the type of the output (see -Details) (default: \code{"Interval"}).} - \item{ambiguity}{(optional) a \code{numeric} or \code{NA} value to instruct \code{assign_date()} on how to deal with ambiguities (see Details) (default: \code{0}).} - -\item{start_name, end_name}{(optional) a string indicating a name associated -with the \code{start} and \code{end} argument.} } \value{ -\itemize{ -\item If \code{return = "Interval"}, a \code{start}--\code{end} \code{Interval} object. -\item If \code{return = "list"}, a named list with \code{start} and \code{end} as elements. -\item If \verb{return = "start}, only the \code{start} output. -\item If \code{return = "end"}, only the \code{end} output. -} +A \code{start}--\code{end} \code{Interval} object. } \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#maturing}{\figure{lifecycle-maturing.svg}{options: alt='[Maturing]'}}}{\strong{[Maturing]}} \code{assign_date()} assign dates to two sequential hours. It can facilitate -time arithmetic by locating time values without date reference on a +time arithmetic by locating time values without a date reference on a timeline. } \details{ @@ -77,39 +59,29 @@ hours, i.e., \code{start} and \code{end} distance themselves by one day. } } -\subsection{\code{return} argument}{ +\subsection{Base date and timezone}{ -\code{assign_date()} can return different outputs: -\itemize{ -\item \code{return = "Interval"}: returns a \code{start}--\code{end} \code{Interval} object. -\item \code{return = "list"}: returns a \code{list} object with two named elements -corresponding to \code{start} and \code{end} output. -\item \code{return = "start"}: returns only the \code{start} output. -\item \code{return = "end"}: returns only the \code{end} output. -} -} +\code{assign_date()} uses the +\href{https://en.wikipedia.org/wiki/Unix_time}{Unix epoch} (1970-01-01) date as +the start date for creating intervals. -\subsection{\code{start_name} and \code{end_name} arguments}{ - -These arguments serve to instruct \code{assign_date()} on how to name the -list elements when \code{return = "list"}. By default, the function will name -these elements with the names of the variables assigned to \code{start} and \code{end} -arguments. - -If the number of characters (\code{nchar()}) of \code{start_name} or \code{end_name} are -equal or greater than 30, \code{assign_date()} will name the list elements as -\code{"start"} and \code{"end"}. +The output will always have \code{"UTC"} set as timezone. Learn more about +time zones in \link[base:timezones]{base::timezone}. } \subsection{\code{POSIXt} objects}{ -\code{POSIXt} values passed as argument to \code{start} or \code{end} will be stripped of +\code{POSIXt} objects passed as argument to \code{start} or \code{end} will be stripped of their dates. Only the time will be considered. + +Both \code{POSIXct} and \code{POSIXlt} are objects that inherits the class \code{POSIXt}. +Learn more about it in \link[base:DateTimeClasses]{base::DateTimeClasses}. } \subsection{\code{NA} values}{ -\code{assign_date()} will return \code{NA} if \code{start} or \code{end} are \code{NA}. +\code{assign_date()} will return an \code{Interval} \code{NA}-\code{NA} if \code{start} or \code{end} are +\code{NA}. } } \examples{ @@ -138,33 +110,6 @@ assign_date(start, end) #> [1] 1970-01-01 09:45:00 UTC--1970-01-01 21:15:00 UTC # Expected #> [2] 1970-01-01 20:30:00 UTC--1970-01-02 04:30:00 UTC # Expected -## To return `start` and `end` as interval (default) - -start <- hms::parse_hm("12:34") -end <- hms::parse_hm("01:25") -assign_date(start, end) -#> [1] 1970-01-01 12:34:00 UTC--1970-01-02 01:25:00 UTC # Expected - -## To return `start` and `end` as list - -start <- hms::parse_hm("22:15") -end <- hms::parse_hm("00:01") -assign_date(start, end, return = "list") -#> $start # Expected -#> [1] "1970-01-01 22:15:00 UTC" # Expected -#> # Expected -#> $end # Expected -#> [1] "1970-01-02 00:01:00 UTC" # Expected - -## To return only `start` or `end` - -start <- lubridate::parse_date_time("01:10:00", "HMS") -end <- lubridate::parse_date_time("11:45:00", "HMS") -assign_date(start, end, return = "start") -#> [1] "1970-01-01 01:10:00 UTC" # Expected -assign_date(start, end, return = "end") -#> [1] "1970-01-01 11:45:00 UTC" # Expected - ## To assign a 24 hours interval to ambiguities start <- lubridate::as_datetime("1985-01-15 12:00:00") diff --git a/tests/testthat/test-assign_date.R b/tests/testthat/test-assign_date.R index 48c45ea..f8bbe62 100644 --- a/tests/testthat/test-assign_date.R +++ b/tests/testthat/test-assign_date.R @@ -37,62 +37,10 @@ test_that("assign_date() | `ambiguity` test", { lubridate::as.interval(NA)) }) -test_that("assign_date() | `return` test", { - expect_equal(assign_date(hms::parse_hm("22:15"), - hms::parse_hm("00:00"), - return = "list", - start_name = "start", - end_name = "end"), - list(start = lubridate::as_datetime("1970-01-01 22:15:00"), - end = lubridate::as_datetime("1970-01-02 00:00:00"))) - - expect_equal(assign_date(hms::parse_hm("01:10"), - hms::parse_hm("11:45"), - return = "list", - start_name = "start", - end_name = "end"), - list(start = lubridate::as_datetime("1970-01-01 01:10:00"), - end = lubridate::as_datetime("1970-01-01 11:45:00"))) - - expect_equal(assign_date(lubridate::parse_date_time("01:10:00", "HMS"), - lubridate::parse_date_time("11:45:00", "HMS"), - return = "start"), - lubridate::as_datetime("1970-01-01 01:10:00")) - - expect_equal(assign_date(lubridate::parse_date_time("01:10:00", "HMS"), - lubridate::parse_date_time("11:45:00", "HMS"), - return = "end"), - lubridate::as_datetime("1970-01-01 11:45:00")) - - expect_equal(assign_date(lubridate::parse_date_time("21:45:00", "HMS"), - lubridate::parse_date_time("03:20:00", "HMS"), - return = "start"), - lubridate::as_datetime("1970-01-01 21:45:00")) - - expect_equal(assign_date(lubridate::parse_date_time("21:45:00", "HMS"), - lubridate::parse_date_time("03:20:00", "HMS"), - return = "end"), - lubridate::as_datetime("1970-01-02 03:20:00")) -}) - -test_that("assign_date() | `start_name` and `end_name` test", { - checkmate::expect_names(names(assign_date(hms::parse_hm("23:00"), - hms::parse_hm("01:00"), - return = "list")), - identical.to = c('hms::parse_hm("23:00")', - 'hms::parse_hm("01:00")')) -}) - test_that("assign_date() | error test", { expect_error(assign_date(1, hms::hms(1)), "Assertion on 'start' failed") expect_error(assign_date(hms::hms(1), 1), "Assertion on 'end' failed") expect_error(assign_date(hms::hms(1), c(hms::hms(1), hms::hms(1)))) - expect_error(assign_date(hms::hms(1), hms::hms(1) , return = "x"), - "Assertion on 'tolower\\(return\\)' failed") expect_error(assign_date(hms::hms(1), hms::hms(1) , ambiguity = "x"), "Assertion on 'ambiguity' failed") - expect_error(assign_date(hms::hms(1), hms::hms(1) , start_name = 1), - "Assertion on 'start_name' failed") - expect_error(assign_date(hms::hms(1), hms::hms(1) , end_name = 1), - "Assertion on 'end_name' failed") })