Whenever I need to work with date-times and want to split the data into a date and its time component, I feel frustrated because the existing tools I'm familiar with (lubridate, clock) make this task quite difficult. Perhaps I'm missing something.
I think hms could offer lightweight tools for splitting and recombining, e.g., hms_separate() and hms_unite() . The result of hms_separate() would be a three-column tibble with components:
date: Date
time: hms
tz: the "zone", "isdst" and "gmtoff" components from POSIXlt
This implementation would be oblivious of leap seconds and such, but instead aim at being "good enough" for most practical cases.
The experiment below demonstrates a roundtrip for this decomposition for a timespan of over four years, with at least one timepoint in each hour.
ct <- structure(1675058104.91011, class = c("POSIXct", "POSIXt"), tzone = "") - seq(0, 14e7, by = 59)
# ct <- ct[2213:2217]
# ct <- head(ct, 100)
ct[[1]]
#> [1] "2023-01-30 06:55:04 CET"
t <- as.POSIXlt(ct)
# Get components that are sufficient for a roundtrip
tp <- hms::as_hms(t)
dp <- as.Date(t)
tzp <- unclass(t)[c("zone", "isdst", "gmtoff")]
# Helper
tp_decompose <- function(x) {
x <- as.numeric(x)
seconds <- x %% 60
x <- x - seconds
x <- as.integer(round(x / 60))
minutes <- as.integer(round(x %% 60))
x <- x - minutes
x <- as.integer(round(x / 60))
hours <- x
list(hour = hours, min = minutes, sec = seconds)
}
# Implement roundtrip
tpd <- tp_decompose(tp)
ptt <- as.POSIXlt(dp)
attr(ptt, "tzone") <- attr(t, "tzone")
ptt <- unclass(ptt)
ptt[names(tpd)] <- tpd
ptt[names(tzp)] <- tzp
class(ptt) <- c("POSIXlt", "POSIXt")
# Check roundtrip
identical(t, ptt)
#> [1] TRUE
tt <- as.POSIXct(ptt)
identical(ct, tt)
#> [1] TRUE
Whenever I need to work with date-times and want to split the data into a date and its time component, I feel frustrated because the existing tools I'm familiar with (lubridate, clock) make this task quite difficult. Perhaps I'm missing something.
I think hms could offer lightweight tools for splitting and recombining, e.g.,
hms_separate()
andhms_unite()
. The result ofhms_separate()
would be a three-column tibble with components:date
:Date
time
:hms
tz
: the "zone", "isdst" and "gmtoff" components fromPOSIXlt
This implementation would be oblivious of leap seconds and such, but instead aim at being "good enough" for most practical cases.
The experiment below demonstrates a roundtrip for this decomposition for a timespan of over four years, with at least one timepoint in each hour.
Created on 2023-01-30 with reprex v2.0.2