2

可能重复:
R 如何用小数秒格式化 POSIXct

我熟悉这个关于“R 如何用小数秒格式化 POSIXct”的问题。接下来有一个论点,关于 POSIXct 在处理微秒时是否存在数字错误。

在我重新实现一整套可以在微秒内无错误地处理的 xts 功能之前(xts 没有问题 - 只是它需要 POSIXct),我只是想确保:

为什么下一行的输出是 4.577894?

as.POSIXlt(as.POSIXct(sprintf("%s",(format(as.POSIXct("2012-12-14 15:42:04.577895 EDT"), "%Y-%m-%d %H:%M:%OS6")))))$sec

非常感谢!

EDIT

这背后的原因如下:如果我正在从文件中读取时间条目,进行一些处理,再次写入文件,再次读取等,我会累积错误。所以 - 这不是一个“技巧”问题,但实际上是经过数小时的调试..

4

2 回答 2

3

这个问题已经讨论得太久了——尤其是考虑到问题本身与答案相关联。

这是一个输出表示问题,并且是众所周知的。舍入时间值具有影响。在某些情况下,您不能只四舍五入亚秒级值而不会得到不正确的结果。

解决方案在这里(如问题中的链接): R如何用小数秒格式化POSIXct

直接从 Aaron 的优秀答案中窃取:

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=""))
}

x <- as.POSIXct("2012-12-14 15:42:04.577895 EDT")

你正在尝试什么:

as.POSIXlt(as.POSIXct(sprintf("%s",(format(x, "%Y-%m-%d %H:%M:%OS6")))))$sec
## [1] 4.577894

亚伦的代码:

myformat.POSIXct(x, 6)
## [1] "2012-12-14 15:42:04.577895"

有人可能会考虑使用sprintf格式字符串%.06f来格式化亚秒值,但如果该值略低于整数,这将失败:

sprintf('%.06f', .9999999)
## [1] "1.000000"

如果亚秒值向上舍入,则转换为 POSIXlt 会导致正确的翻转为秒、分钟等。

向您表明这不是数据问题:

y <- as.numeric(x)
y
## [1] 1355521324.5778949261
sprintf('%06f', y - floor(y))
## [1] "0.577895"
于 2013-02-05T14:37:46.310 回答
0

我认为您所引用的 SO 问题的评论中指出了您的问题的答案。问题是转换为 POSIXct 或 POSIXlt 包含舍入。只需为您的价值和转换权本身添加一个小偏移量。

# Original value
format(as.POSIXct("2012-12-14 15:42:04.577895 EDT"), "%Y-%m-%d %H:%M:%OS6")
[1] "2012-12-14 15:42:04.577894"

# Original value + offset
format(as.POSIXlt("2012-12-14 15:42:04.5778951 EDT"), "%Y-%m-%d %H:%M:%OS6")
[1] "2012-12-14 15:42:04.577895"

我建议使用正则表达式来添加偏移量,如下所示:

gsub(" (\\w+)$","1 \\1","2012-12-14 15:42:04.577895 EDT")
[1] "2012-12-14 15:42:04.5778951 EDT"
于 2013-02-04T13:21:24.090 回答