From 8953cbce0adb0abdeca36aeb18014d78a2f05c4d Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Tue, 19 Nov 2024 09:31:16 -0600 Subject: [PATCH 1/3] Simplify format.POSIXlt() to improve bugzilla issue 17350 there is also a bit of whitespace change as the indentation was off for under Emacs/ESS which is unusual for base R code. --- src/library/base/R/datetime.R | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/library/base/R/datetime.R b/src/library/base/R/datetime.R index f870e95a966..208175ec016 100644 --- a/src/library/base/R/datetime.R +++ b/src/library/base/R/datetime.R @@ -384,19 +384,12 @@ format.POSIXlt <- function(x, format = "", usetz = FALSE, if(!inherits(x, "POSIXlt")) stop("wrong class") if(any(f0 <- format == "")) { ## need list [ method here. - times <- unlist(unclass(x)[1L:3L])[f0] - secs <- x$sec[f0]; secs <- secs[is.finite(secs)] + times <- unlist(unclass(x)[1L:3L])[f0] np <- if(is.null(digits)) 0L else min(6L, digits) - if(np >= 1L) # no unnecessary trailing '0' : - for (i in seq_len(np)- 1L) - if(all( abs(secs - round(secs, i)) < 1e-6 )) { - np <- i - break - } - format[f0] <- - if(all(times[is.finite(times)] == 0)) "%Y-%m-%d" - else if(np == 0L) "%Y-%m-%d %H:%M:%S" - else paste0("%Y-%m-%d %H:%M:%OS", np) + format[f0] <- + if(all(times[is.finite(times)] == 0)) "%Y-%m-%d" + else if(np == 0L) "%Y-%m-%d %H:%M:%S" + else paste0("%Y-%m-%d %H:%M:%OS", np) } .Internal(format.POSIXlt(x, format, usetz)) } From fa7b99bf9f6d4aed6794e14c72ea416fe002c941 Mon Sep 17 00:00:00 2001 From: Dirk Eddelbuettel Date: Tue, 19 Nov 2024 16:00:54 -0600 Subject: [PATCH 2/3] Refine condition and update help page As discussed and co-developed with @hturner --- src/library/base/R/datetime.R | 2 +- src/library/base/man/strptime.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/library/base/R/datetime.R b/src/library/base/R/datetime.R index 208175ec016..d08df9acbde 100644 --- a/src/library/base/R/datetime.R +++ b/src/library/base/R/datetime.R @@ -382,7 +382,7 @@ format.POSIXlt <- function(x, format = "", usetz = FALSE, digits = getOption("digits.secs"), ...) { if(!inherits(x, "POSIXlt")) stop("wrong class") - if(any(f0 <- format == "")) { + if(any(f0 <- format == "" | grepl("%OS$", format))) { ## need list [ method here. times <- unlist(unclass(x)[1L:3L])[f0] np <- if(is.null(digits)) 0L else min(6L, digits) diff --git a/src/library/base/man/strptime.Rd b/src/library/base/man/strptime.Rd index 9ab47d2010c..9a576171822 100644 --- a/src/library/base/man/strptime.Rd +++ b/src/library/base/man/strptime.Rd @@ -39,7 +39,7 @@ strptime(x, format, tz = "") methods is \code{"\%Y-\%m-\%d \%H:\%M:\%S"} if any element has a time component which is not midnight, and \code{"\%Y-\%m-\%d"} - otherwise. If \code{\link{options}("digits.secs")} is set, up to + otherwise. If \code{\link{options}("digits.secs")} is set, the specified number of digits will be printed for seconds.} \item{\dots}{further arguments to be passed from or to other methods.} \item{usetz}{logical. Should the time zone abbreviation be appended From 60c64de38590bf171fc6ff22b1f4d97430127d76 Mon Sep 17 00:00:00 2001 From: Heather Turner Date: Wed, 20 Nov 2024 12:25:03 +0000 Subject: [PATCH 3/3] reinstate np loop but use truncation --- src/library/base/R/datetime.R | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/library/base/R/datetime.R b/src/library/base/R/datetime.R index d08df9acbde..a3d5a23bc1a 100644 --- a/src/library/base/R/datetime.R +++ b/src/library/base/R/datetime.R @@ -384,12 +384,19 @@ format.POSIXlt <- function(x, format = "", usetz = FALSE, if(!inherits(x, "POSIXlt")) stop("wrong class") if(any(f0 <- format == "" | grepl("%OS$", format))) { ## need list [ method here. - times <- unlist(unclass(x)[1L:3L])[f0] + times <- unlist(unclass(x)[1L:3L])[f0] + secs <- x$sec[f0]; secs <- secs[is.finite(secs)] np <- if(is.null(digits)) 0L else min(6L, digits) - format[f0] <- - if(all(times[is.finite(times)] == 0)) "%Y-%m-%d" - else if(np == 0L) "%Y-%m-%d %H:%M:%S" - else paste0("%Y-%m-%d %H:%M:%OS", np) + if(np >= 1L) # no unnecessary trailing '0' : + for (i in seq_len(np)- 1L) + if(all( abs(secs - trunc(secs*10^i)/10^i) < 1e-6 )) { + np <- i + break + } + format[f0] <- + if(all(times[is.finite(times)] == 0)) "%Y-%m-%d" + else if(np == 0L) "%Y-%m-%d %H:%M:%S" + else paste0("%Y-%m-%d %H:%M:%OS", np) } .Internal(format.POSIXlt(x, format, usetz)) }