2 回答
TA贡献1818条经验 获得超11个赞
一个潜在的问题是POSIXct表示不如POSIXlt表示精确,并且POSIXct表示在格式化之前转换为POSIXlt表示。下面我们看到如果我们的字符串直接转换为POSIXlt表示,它输出正确。
> as.POSIXct('2011-10-11 07:49:36.3')
[1] "2011-10-11 07:49:36.2 CDT"
> as.POSIXlt('2011-10-11 07:49:36.3')
[1] "2011-10-11 07:49:36.3"
我们还可以通过查看两种格式的二进制表示与0.3的通常表示之间的差异来看到。
> t1 <- as.POSIXct('2011-10-11 07:49:36.3')
> as.numeric(t1 - round(unclass(t1))) - 0.3
[1] -4.768372e-08
> t2 <- as.POSIXlt('2011-10-11 07:49:36.3')
> as.numeric(t2$sec - round(unclass(t2$sec))) - 0.3
[1] -2.831069e-15
有趣的是,看起来两个表示实际上都比0.3的通常表示要小,但是第二个表示要么足够接近,要么截断的方式与我想象的不同。鉴于此,我不会担心浮点表示困难; 它们可能仍然会发生,但如果我们小心使用哪种表示方式,它们有望最小化。
罗伯特对圆形输出的渴望只是输出问题,可以通过多种方式解决。我的建议是这样的:
myformat.POSIXct <- function(x, digits=0) {
x2 <- round(unclass(x), digits)
attributes(x2) <- attributes(x)
x <- as.POSIXlt(x2)
x$sec <- round(x$sec, digits)
format.POSIXlt(x, paste("%Y-%m-%d %H:%M:%OS",digits,sep=""))
}
这从POSIXct输入开始,并首先轮到所需的数字; 然后转换为POSIXlt并再次舍入。第一轮舍入确保当我们处于分钟/小时/天边界时所有单元都适当增加; 转换为更精确的表示后的第二轮四舍五入。
> options(digits.secs=1)
> t1 <- as.POSIXct('2011-10-11 07:49:36.3')
> format(t1)
[1] "2011-10-11 07:49:36.2"
> myformat.POSIXct(t1,1)
[1] "2011-10-11 07:49:36.3"
> t2 <- as.POSIXct('2011-10-11 23:59:59.999')
> format(t2)
[1] "2011-10-11 23:59:59.9"
> myformat.POSIXct(t2,0)
[1] "2011-10-12 00:00:00"
> myformat.POSIXct(t2,1)
[1] "2011-10-12 00:00:00.0"
最后一个:你知道标准允许最多两个闰秒吗?
> as.POSIXlt('2011-10-11 23:59:60.9')
[1] "2011-10-11 23:59:60.9"
好的,还有一件事。由于OP提交的错误,该行为实际上在5月发生了变化(错误14579); 在那之前,它确实是小数秒。不幸的是,这意味着有时它可以绕到一秒钟是不可能的; 在错误报告中,当它应该转到下一分钟时,它上升到60。决定截断而不是舍入的一个原因是它是从POSIXlt表示打印的,其中每个单元是分开存储的。因此,滚动到下一分钟/小时/等比仅仅简单的舍入操作更困难。要轻松舍入,有必要在POSIXct表示中进行舍入,然后按照我的建议转换回来。
- 2 回答
- 0 关注
- 957 浏览
添加回答
举报