1#' @include timespans.r 2#' @include durations.r 3#' @include intervals.r 4#' @include periods.r 5 6 7setOldClass("difftime") 8 9#' Create a difftime object. 10#' 11#' `make_difftime()` creates a difftime object with the specified number of 12#' units. Entries for different units are cumulative. difftime displays 13#' durations in various units, but these units are estimates given for 14#' convenience. The underlying object is always recorded as a fixed number of 15#' seconds. 16#' 17#' Conceptually, difftime objects are a type of duration. They measure the 18#' exact passage of time but do not always align with measurements 19#' made in larger units of time such as hours, months and years. 20#' This is because the length of larger time units can be affected 21#' by conventions such as leap years 22#' and Daylight Savings Time. \pkg{lubridate} provides a second class for measuring durations, the Duration class. 23#' @param num Optional number of seconds 24#' @param units a character vector that lists the type of units to use for the 25#' display of the return value (see examples). If `units` is "auto" (the 26#' default) the display units are computed automatically. This might create 27#' undesirable effects when converting `difftime` objects to numeric 28#' values in data processing. 29#' @param ... a list of time units to be included in the difftime and their amounts. Seconds, 30#' minutes, hours, days, and weeks are supported. Normally only one of `num` or `...` are present. If 31#' both are present, the `difftime` objects are concatenated. 32#' @return a difftime object 33#' @seealso [duration()], [as.duration()] 34#' @keywords chron classes 35#' @export 36#' @examples 37#' make_difftime(1) 38#' make_difftime(60) 39#' make_difftime(3600) 40#' make_difftime(3600, units = "minute") 41#' # Time difference of 60 mins 42#' make_difftime(second = 90) 43#' # Time difference of 1.5 mins 44#' make_difftime(minute = 1.5) 45#' # Time difference of 1.5 mins 46#' make_difftime(second = 3, minute = 1.5, hour = 2, day = 6, week = 1) 47#' # Time difference of 13.08441 days 48#' make_difftime(hour = 1, minute = -60) 49#' # Time difference of 0 secs 50#' make_difftime(day = -1) 51#' # Time difference of -1 days 52#' make_difftime(120, day = -1, units = "minute") 53#' # Time differences in mins 54make_difftime <- function(num = NULL, units = "auto", ...) { 55 pieces <- list(...) 56 if (!is.null(num) && length(pieces) > 0) { 57 .difftime_from_num(c(num, .difftime_from_pieces(pieces)), units) 58 } else if (!is.null(num)) { 59 .difftime_from_num(num, units) 60 } else if (length(pieces)) { 61 .difftime_from_num(.difftime_from_pieces(pieces), units) 62 } else { 63 stop("No valid values have been passed to 'make_difftime' constructor") 64 } 65} 66 67difftime_lengths <- c(secs = 1, mins = 60, hours = 3600, days = 86400, weeks = 7 * 86400) 68 69.difftime_from_num <- function(num, units = "auto") { 70 seconds <- abs(na.omit(num)) 71 units <- units[[1]] 72 if (units == "auto") { 73 if (any(seconds < 60)) 74 units <- "secs" 75 else if (any(seconds < 3600)) 76 units <- "mins" 77 else if (any(seconds < 86400)) 78 units <- "hours" 79 else 80 units <- "days" 81 } else { 82 units <- standardise_difftime_names(units) 83 } 84 structure(num/difftime_lengths[[units]], units = units, class = "difftime") 85} 86 87.difftime_from_pieces <- function(pieces) { 88 names(pieces) <- standardise_difftime_names(names(pieces)) 89 out <- 0 90 for (nm in names(pieces)) 91 out <- out + pieces[[nm]] * difftime_lengths[[nm]] 92 out 93} 94 95#' Is x a difftime object? 96#' 97#' @export is.difftime 98#' @param x an R object 99#' @return TRUE if x is a difftime object, FALSE otherwise. 100#' @seealso [is.instant()], [is.timespan()], [is.interval()], 101#' [is.period()]. 102#' @keywords logic chron 103#' @examples 104#' is.difftime(as.Date("2009-08-03")) # FALSE 105#' is.difftime(make_difftime(days = 12.4)) # TRUE 106is.difftime <- function(x) is(x, "difftime") 107