我想使用Posix时间中的Sys.Date()来获取昨天的最后一分钟。

force_tz(as.POSIXlt(Sys.Date()-1), tz = 'America/New_York') + 86399
# [1] "2018-01-12 23:59:59 EST"


正确

force_tz(as.POSIXct(Sys.Date()-1), tz = 'America/New_York') + 86399
# [1] "2018-01-12 15:59:59 EST"


不正确

Sys.Date()
# [1] "2018-01-13"


为什么as.Posixctas.Posixlt使用Sys.Date()返回两个不同的值,为什么即使从force_tz应用lubridate后8个小时仍会有差异?

最佳答案

和以往一样,debugonce是您的朋友。运行debugonce(force_tz),您可以看到输出的差异来自force_tz首先检查is.POSIXct(time)击中分支的情况(在这种情况下,将应用默认的tzone = "")。在POSIXlt情况下,将命中默认分支,其中as.POSIXct应用于time,并且tz(time)(对于UTC对象以POSIXlt形式出现)用作时区。



这归结为一些微妙的事情。来自?as.POSIXlt.Date


没有时间的日期视为UTC午夜。


因此

tz(as.POSIXlt(Sys.Date()-1))
# [1] "UTC"




tz(as.POSIXct(Sys.Date()-1))
# [1] ""


奇怪的是,这不能被覆盖-as.POSIXlt.Date不接受tz参数:

formals(as.POSIXlt.Date)
# $x
# $...




如果要使用POSIXct,以下内容如何?

force_tz(as.POSIXct(sprintf('%s 00:00:00', Sys.Date())), 'America/New_York') - 1L
# [1] "2018-01-12 23:59:59 EST"

09-17 13:46