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 關注
- 989 瀏覽
添加回答
舉報