Nothing
#' Time-zone manipulation
#'
#' @description `time_at_tz` returns a date-time as it would appear in a
#' different time zone. The actual moment of time measured does not change,
#' just the time zone it is measured in. `time_at_tz` defaults to the
#' Universal Coordinated time zone (UTC) when an unrecognized time zone is
#' supplied.
#'
#' @param time a date-time object (POSIXct, POSIXlt, Date) or a list of
#' date-time objects. When a list, all contained elements are updated the new
#' list is returned.
#' @param tz a character string containing the time zone to convert to. R must
#' recognize the name contained in the string as a time zone on your
#' system. For `time_force_tz` and `time_clock_at_tzs`, `tz` can be a vector
#' of heterogeneous time-zones, in which case `time` and `tz` arguments are
#' paired. If `time` and `tz` lengths differ, the smaller one is recycled
#' according with usual R conventions.
#' @return a POSIXct object with the updated time zone
#' @name time-zones
#' @examples
#'
#' x <- as.POSIXct("2009-08-07 00:00:00", tz = "America/New_York")
#' time_at_tz(x, "UTC")
#' time_force_tz(x, "UTC")
#' time_force_tz(x, "Europe/Amsterdam")
#'
#'
#' ## DST skip:
#'
#' y <- as.POSIXct("2010-03-14 02:05:05", tz = "UTC")
#' time_force_tz(y, "America/New_York", roll = "boundary")
#' time_force_tz(y, "America/New_York", roll = "post")
#' time_force_tz(y, "America/New_York", roll = "pre")
#' time_force_tz(y, "America/New_York", roll = "NA")
#'
#'
#' ## DST skipped and repeated
#'
#' y <- as.POSIXct(c("2010-03-14 02:05:05 UTC", "2014-11-02 01:35:00"), tz = "UTC")
#' time_force_tz(y, "America/New_York", roll_dst = c("NA", "pre"))
#' time_force_tz(y, "America/New_York", roll_dst = c("boundary", "post"))
#'
#' ## Heterogeneous time-zones:
#'
#' x <- as.POSIXct(c("2009-08-07 00:00:01", "2009-08-07 01:02:03"), tz = "UTC")
#' time_force_tz(x, tz = c("America/New_York", "Europe/Amsterdam"))
#' time_force_tz(x, tz = c("America/New_York", "Europe/Amsterdam"), tzout = "America/New_York")
#'
#' x <- as.POSIXct("2009-08-07 00:00:01", tz = "UTC")
#' time_force_tz(x, tz = c("America/New_York", "Europe/Amsterdam"))
#'
#' ## Local clock:
#' x <- as.POSIXct(c("2009-08-07 01:02:03", "2009-08-07 10:20:30"), tz = "UTC")
#' time_clock_at_tz(x, units = "secs")
#' time_clock_at_tz(x, units = "hours")
#' time_clock_at_tz(x, "Europe/Amsterdam")
#'
#' x <- as.POSIXct("2009-08-07 01:02:03", tz = "UTC")
#' time_clock_at_tz(x, tz = c("America/New_York", "Europe/Amsterdam", "Asia/Shanghai"), unit = "hours")
#' @export
time_at_tz <- function(time, tz = "UTC") {
if (!C_valid_tz(tz))
warning(sprintf("Unrecognized time zone '%s'", tz))
if (is.list(time) && !is.POSIXlt(time)) {
for (nm in names(time)) {
if (is.instant(time[[nm]])) {
time[[nm]] <- .at_tz(time[[nm]], tz)
}
}
time
} else {
.at_tz(time, tz)
}
}
.at_tz <- function(time, tz) {
posixlt <- is.POSIXlt(time)
new <-
if (posixlt) as.POSIXct(time)
else time
attr(new, "tzone") <- tz
if (posixlt) as.POSIXlt.POSIXct(new)
else new
}
#' @description `time_force_tz` returns the date-time that has the same clock
#' time as input time, but in the new time zone. Although the new date-time
#' has the same clock time (e.g. the same values in the seconds, minutes,
#' hours, etc.) it is a different moment of time than the input
#' date-time. Computation is vectorized over both `time` and `tz` arguments.
#'
#' @param roll_dst same as in `time_add` which see.
#' @param tzout timezone of the output date-time vector. Meaningful only when
#' `tz` argument is a vector of heterogenuous time-zones. This argument is
#' necessary because R date-time vectors cannot hold elements with different
#' time-zones.
#' @name time-zones
#' @export
time_force_tz <- function(time, tz = "UTC", tzout = tz[[1]], roll_dst = c("boundary", "post")) {
if (is.list(time) && !is.POSIXlt(time)) {
for (nm in names(time)) {
if (is.instant(time[[nm]])) {
time[[nm]] <- .force_tz(time[[nm]], tz, tzout, roll_dst)
}
}
time
} else {
.force_tz(time, tz, tzout, roll_dst)
}
}
.force_tz <- function(time, tz, tzout, roll_dst) {
if (length(tz) == 1L && tz == tzout) {
from_posixct(C_force_tz(to_posixct(time), tz, roll_dst), time)
} else {
if (length(tz) < length(time))
tz <- rep_len(tz, length(time))
else if (length(tz) > length(time)) {
attr <- attributes(time)
time <- rep_len(time, length(tz))
attributes(time) <- attr
}
from_posixct(C_force_tzs(to_posixct(time), tz, tzout, roll_dst), time)
}
}
#' @description `time_clock_at_tz` retrieves day clock time in specified time
#' zones. Computation is vectorized over both `dt` and `tz` arguments, `tz`
#' defaults to the timezone of `time`.
#'
#' @param units passed directly to [as.difftime()].
#' @name time-zones
#' @export
time_clock_at_tz <- function(time, tz = NULL, units = "secs") {
if (is.list(time) && !is.POSIXlt(time)) {
for (nm in names(time)) {
if (is.instant(time[[nm]])) {
time[[nm]] <- .clock_at_tz(time[[nm]], tz, units)
}
}
time
} else {
time <-
if (is.Date(time)) date_to_posixct(time, tz(time))
else as.POSIXct(time)
.clock_at_tz(time, tz, units)
}
}
.clock_at_tz <- function(time, tz, units) {
if (is.null(tz))
tz <- tz(time)
## FIXME: don't replicate tz when len == 1; follow vctrs and lubridate replication
## convention
if (length(tz) < length(time))
tz <- rep_len(tz, length(time))
else if (length(tz) > length(time)) {
attr <- attributes(time)
time <- rep_len(time, length(tz))
attributes(time) <- attr
}
# Catch rare integer POSIXct, retaining attributes
storage.mode(time) <- "double"
secs <- C_local_clock(time, tz)
out <- structure(secs, units = "secs", class = "difftime")
units(out) <- units
out
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.