Posixlt 和 Posixct 中的系统日期

System date in Posixlt and Posixct

我正在尝试在 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 return 使用 Sys.Date() 两个不同的值,为什么即使从 [= 应用 force_tz 后仍相差 8 小时18=] ?

一如既往,debugonce 是你的朋友。 运行 debugonce(force_tz),您可以看到输出的差异来自于 force_tz 首先检查分支 is.POSIXct(time)(在这种情况下应用默认 tzone = "" );在 POSIXlt 的情况下,默认分支被命中,其中 as.POSIXct 应用于 timetz(time) (对于 [=19 结果为 UTC =] object) 用作时区。


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

Dates without times are treated as being at midnight 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"