Permalink
60 lines (52 sloc) 1.79 KB
#' Converts a date to a decimal of its year
#'
#' @export
#' @param date a POSIXt or Date object
#' @return a numeric object where the date is expressed as a fraction of its year
#' @keywords manip chron methods
#' @examples
#' date <- ymd("2009-02-10")
#' decimal_date(date) # 2009.11
decimal_date <- function(date)
UseMethod("decimal_date")
#' @export
decimal_date.default <- function(date) {
if (any(!inherits(date, c("POSIXt", "POSIXct", "POSIXlt", "Date"))))
stop("date(s) not in POSIXt or Date format")
Y <- year(date)
start <- make_datetime(Y, 1L, 1L, tz = tz(date))
end <- make_datetime(Y + 1L, 1L, 1L, tz = tz(date))
sofar <- as.numeric(difftime(date, start, units = "secs"))
total <- as.numeric(difftime(end, start, units = "secs"))
Y + sofar/total
}
#' @export
decimal_date.zoo <- function(date)
decimal_date(zoo::index(date))
## #' @export
## decimal_date.its <- function(date)
## decimal_date.default(attr(date, "dates"))
#' Converts a decimal to a date
#'
#' @export
#' @param decimal a numeric object
#' @param tz the time zone required
#' @return a POSIXct object, whose year corresponds to the integer part of
#' decimal. The months, days, hours, minutes and seconds elements are picked so
#' the date-time will accurately represent the fraction of the year expressed by
#' decimal.
#' @keywords manip chron methods
#' @examples
#' date <- ymd("2009-02-10")
#' decimal <- decimal_date(date) # 2009.11
#' date_decimal(decimal) # "2009-02-10 UTC"
date_decimal <- function(decimal, tz = "UTC") {
Y <- trunc(decimal)
## parsing is much faster than updating
start <- make_datetime(Y, 1L, 1L, tz = tz)
end <- make_datetime(Y + 1L, 1L, 1L, tz = tz)
seconds <- as.numeric(difftime(end, start, units = "secs"))
frac <- decimal - Y
end <- start + seconds*frac
return(end)
}