Posixlt和Posixct中的系统日期

3
我正在尝试使用 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"

为什么使用Sys.Date()时,as.Posixctas.Posixlt返回两个不同的值?即使使用lubridate中的force_tz强制指定时区后,差异仍为8小时?

1个回答

2
作为常规操作,debugonce是你的好朋友。运行debugonce(force_tz),你会发现输出的差异来自于force_tz命中首先检查is.POSIXct(time)的分支时(在这种情况下应用默认的tzone = ""); 在POSIXlt情况下,命中默认分支,在该分支中将time应用于as.POSIXct并使用tz(time)(对于POSIXlt对象,其结果为UTC)作为时区。


这归结于一些微妙的事情;来自?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"

@the_darkside 我终于对我的回答感到满意,覆盖了你的问题;如果我漏掉了什么,请跟进。 - MichaelChirico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接