[Rd] Floating Point with POSIXct
John Muschelli
mu@che|||j2 @end|ng |rom gm@||@com
Thu Mar 3 17:04:05 CET 2022
I see in ?POSIXct and I'm trying to understand the note:
> Classes "POSIXct" and "POSIXlt" are able to express fractions of a second. (Conversion of fractions between the two forms may not be exact, but will have better than microsecond accuracy.)
Mainly, I'm trying to understand printing of POSIXct with fractional
seconds. I see print.POSIXct calls format.POSIXct and eventually
calls format.POSIXlt, which then takes into account `digits.secs` for
printing. The format uses %OS3, which strptime indicates (* added):
> Specific to R is %OSn, which for output gives the seconds *truncated* to 0 <= n <= 6 decimal places (and if %OS is not followed by a digit, it uses the setting of getOption("digits.secs"), or if that is unset, n = 0).
So I'm seeing it truncates the seconds to 3 digits, so I think that is
why the below is printing 0.024.
I think this is especially relevant even if you set
`options(digits.secs = 6)`, then the code in
format.POSIXlt would still return np=3 as the following condition
would break at i = 3
for (i in seq_len(np) - 1L) if (all(abs(secs - round(secs,
i)) < 1e-06)) {
np <- i
break
}
as sub_seconds - round(sub_seconds,3) < 1e-06. This seems to be
expected behavior given the docs, but would any consider this a bug?
Example:
options(digits.secs = 4)
x = structure(947016000.025, class = c("POSIXct", "POSIXt"), tzone = "UTC")
summary(x, digits = 20)
#> Min. 1st Qu. Median
#> "2000-01-04 20:00:00.024" "2000-01-04 20:00:00.024" "2000-01-04 20:00:00.024"
#> Mean 3rd Qu. Max.
#> "2000-01-04 20:00:00.024" "2000-01-04 20:00:00.024" "2000-01-04 20:00:00.024"
x
#> [1] "2000-01-04 20:00:00.024 UTC"
format.POSIXct(x, format = "%Y-%m-%d %H:%M:%OS3")
#> [1] "2000-01-04 20:00:00.024"
format.POSIXct(x, format = "%Y-%m-%d %H:%M:%OS4")
#> [1] "2000-01-04 20:00:00.0249"
sub_seconds = as.numeric(x) %% 1
sub_seconds
#> [1] 0.02499998
round(sub_seconds, 3)
#> [1] 0.025
rounded = as.POSIXct(
floor(as.numeric(x)) +
round(as.numeric(x) %% 1, 3),
origin = "1970-01-01")
rounded
#> [1] "2000-01-04 20:00:00.024 UTC"
as.numeric(rounded) %% 1
#> [1] 0.02499998
R.version
_
platform x86_64-pc-linux-gnu
arch x86_64
os linux-gnu
system x86_64, linux-gnu
status
major 4
minor 1.2
year 2021
month 11
day 01
svn rev 81115
language R
version.string R version 4.1.2 (2021-11-01)
nickname Bird Hippie
Best,
John
More information about the R-devel
mailing list