With r82904, 'as.character.POSIXt' in R devel is changed. The NEWS item:
as.character(<POSIXt>) now behaves more in line with the
methods for atomic vectors such as numbers, and is no longer
influenced by options().
Part of the code:
s <- trunc(x$sec)
fs <- x$sec - s
r1 <- sprintf("%d-%02d-%02d", 1900 + x$year, x$mon+1L, x$mday)
if(any(n0 <- time != 0)) # add time if not 0
r1[n0] <- paste(r1[n0],
sprintf("%02d:%02d:%02d%s", x$hour[n0], x$min[n0],
s[n0],
substr(as.character(fs[n0]), 2L, 32L)))
* Wrong:
The result is wrong when as.character(fs[n0]) has scientific notation.
Example (modified from https://bugs.r-project.org/show_bug.cgi?id=9819):
op <- options(scipen = 0, OutDec = ".") # (default setting)
x <- as.POSIXlt("2007-07-27 16:11:03.000002")
as.character(x)
# "2007-07-27 16:11:03.99999999983547e-06"
as.character(x$sec - trunc(x$sec))
# "1.99999999983547e-06"
options(op)
'as.character.POSIXt' could temporarily set option 'scipen' large enough to
prevent scientific notation in as.character(fs[n0]) .
* Too much precision:
In some cases with fractional seconds with seconds close to 60, the result has
many decimal places while there is an accurate representation with less decimal
places. It is actually OK, just unpleasant.
Example (modified from https://bugs.r-project.org/show_bug.cgi?id=14693):
op <- options(scipen = 0, OutDec = ".") # (default setting)
x <- as.POSIXlt("2011-10-01 12:34:56.3")
x$sec == 56.3 # TRUE
print(x$sec, 17)
# [1] 56.299999999999997
as.character(x)
# "2011-10-01 12:34:56.299999999999997"
format(x, "%Y-%m-%d %H:%M:%OS1") # short and accurate
# "2011-10-01 12:34:56.3"
ct <- as.POSIXct(x, tz = "UTC")
identical(ct,
as.POSIXct("2011-10-01 12:34:56.3", tz = "UTC"))
# TRUE
print(as.numeric(ct), 17)
# [1] 1317472496.3
lct <- as.POSIXlt(ct)
lct$sec == 56.3 # FALSE
print(lct$sec, 17)
# [1] 56.299999952316284
as.character(ct)
# "2011-10-01 12:34:56.299999952316284"
options(op)
The "POSIXct" case is a little different because some precision is already lost
after converted to "POSIXct".
In 'as.character.POSIXt', using 'as.character' on the seconds (not separating
the fractional part) might be good enough, but a leading zero must be added as
necessary.
* Different from 'format':
- With fractional seconds, the result is influenced by option 'OutDec'.
- From "Printing years" in ?strptime: "For years 0 to 999 most OSes pad with
zeros or spaces to 4 characters, and Linux outputs just the number."
Because (1900 + x$year) is formatted with %d in 'as.character.POSIXt', years 0
to 999 is output without padding. It is different from 'format' in OSes other
than Linux.
* Behavior with "improper" "POSIXlt" object:
- "POSIXlt" object with out-of-bounds components is not normalized.
Example (modified from regr.tests-1d.R):
op <- options(scipen = 0) # (default setting)
x <- structure(
list(sec = 10000, min = 59L, hour = 18L,
mday = 6L, mon = 11L, year = 116L,
wday = 2L, yday = 340L,
isdst = 0L, zone = "CET", gmtoff = 3600L),
class = c("POSIXlt", "POSIXt"), tzone = "CET")
as.character(x)
# "2016-12-06 18:59:10000"
format(x)
# "2016-12-06 21:45:40"
options(op)
- With "POSIXlt" object where sec, min, hour, mday, mon, and year components
are not all of the same length, recycling is not handled.
Example (modified from regr.tests-1d.R):
op <- options(scipen = 0) # (default setting)
x <- structure(
list(sec = c(1, 2), min = 59L, hour = 18L,
mday = 6L, mon = 11L, year = 116L,
wday = 2L, yday = 340L,
isdst = 0L, zone = "CET", gmtoff = 3600L),
class = c("POSIXlt", "POSIXt"), tzone = "CET")
as.character(x)
# c("2016-12-06 18:59:01", "NA NA:NA:02")
format(x)
# c("2016-12-06 18:59:01", "2016-12-06 18:59:02")
options(op)
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel