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)

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to