我一直在尝试查看一个数据框,提取POSIXct列的日期组件匹配某个值的所有行。我遇到了以下让我非常困惑的问题::as.Date(as.POSIXct(...))
并不总是返回正确的日期。
> dt <- as.POSIXct('2012-08-06 09:35:23')
[1] "2012-08-06 09:35:23 EST"
> as.Date(dt)
[1] "2012-08-05"
为什么'2012-08-06 09:35:23'等于'2012-08-05?
我怀疑这与使用不同的时区有关,所以注意到dt
的时区是'EST',我把它给了as.Date
::
> as.Date(as.POSIXct('2012-08-06 09:35:23'), tz='EST')
[1] "2012-08-05"
但是它仍然返回2012-08-05。
为什么会这样?如何查找数据框中日期为2012-08-06的所有日期时间?(因为subset(my.df, as.character(as.Date(datetime), tz='EST') == '2012-08-06')
不返回具有日期时间dt
的行,即使这确实发生在日期2012-08-06…)?
增加了细节:Linux 64位(虽然可以在32位上复制),可以在R 3.0.1和amp;3.0.0,我现在是AEST(澳大利亚东部标准时间)
安全的方法是通过format
传递日期值。这确实创建了一个额外的步骤,但是如果用"-"或"/"格式化,as.Date
将接受字符结果:
as.Date( format( as.POSIXct('2019-03-11 23:59:59'), "%Y-%m-%d") )
[1] "2019-03-11"
as.Date( as.POSIXct('2019-03-11 23:59:59') ) # I'm in a locale where the problem might exist
[1] "2019-03-12"
时区的文档也让我感到困惑。在某些情况下(在这种情况下),EST可能不是明确的,实际上可能指的是澳大利亚的tz。如果你恰好在北美,试试"EST5EDT"或"America/New_York"。
在这种情况下,它也可能与您未声明的操作系统如何处理'tz'参数的差异有关,因为我得到"2012-08-06"。(我目前在PDT US tz,尽管我不确定这是否重要。)更改获得tz参数的函数可能会澄清(或不澄清):
> as.Date(as.POSIXct('2012-08-06 19:35:23', tz='EST'))
[1] "2012-08-07"
> as.Date(as.POSIXct('2012-08-06 17:35:23', tz='EST'))
[1] "2012-08-06"
> as.Date(as.POSIXct('2012-08-06 21:35:23'), tz='EST')
[1] "2012-08-06"
> as.Date(as.POSIXct('2012-08-06 22:35:23'), tz='EST')
[1] "2012-08-07"
如果省略了as.POSIXct
中的tz,则假定为UTC。
这些是Ozzie TZ的明确名称(至少在我的Mac上):
tzfile <- "/usr/share/zoneinfo/zone.tab"
tzones <- read.delim(tzfile, row.names = NULL, header = FALSE,
col.names = c("country", "coords", "name", "comments"),
as.is = TRUE, fill = TRUE, comment.char = "#")
grep("^Aus", tzones$name, value=TRUE)
[1] "Australia/Lord_Howe" "Australia/Hobart"
[3] "Australia/Currie" "Australia/Melbourne"
[5] "Australia/Sydney" "Australia/Broken_Hill"
[7] "Australia/Brisbane" "Australia/Lindeman"
[9] "Australia/Adelaide" "Australia/Darwin"
[11] "Australia/Perth" "Australia/Eucla"
澳大利亚同胞在这里插话(布里斯班位置,Win7 Enterprise 64位,R3.0.1):
我可以复制你的问题:
> dt <- as.POSIXct('2012-08-06 09:35:23')
> dt
[1] "2012-08-06 09:35:23 EST"
> as.Date(dt)
[1] "2012-08-05"
由于as.Date
默认为UTC
(GMT),如?as.Date
所列:
## S3 method for class 'POSIXct'
as.Date(x, tz = "UTC", ...)
强制POSIXct
表示为UTC然后按预期工作:
> dt <- as.POSIXct('2012-08-06 09:35:23',tz="UTC")
> as.Date(dt)
[1] "2012-08-06"
或者,将它们都匹配到我的本地tz
也可以:
> dt <- as.POSIXct('2012-08-06 09:35:23',tz="Australia/Brisbane")
> as.Date(dt,tz="Australia/Brisbane")
[1] "2012-08-06"
编辑:对我来说,EST
规范的模糊性似乎是一个问题:
默认使用as.POSIXct
> dt.def <- as.POSIXct("2012-01-01 22:00:00")
> dt.def
[1] "2012-01-01 22:00:00 EST"
> as.numeric(dt.def)
[1] 1325419200
>
模棱两可的EST
-应该与默认值
> dt.est <- as.POSIXct("2012-01-01 22:00:00",tz="EST")
> dt.est
[1] "2012-01-01 22:00:00 EST"
> as.numeric(dt.est)
[1] 1325473200
>
明确布里斯班,澳大利亚时区
> dt.bris <- as.POSIXct("2012-01-01 22:00:00",tz="Australia/Brisbane")
> dt.bris
[1] "2012-01-01 22:00:00 EST"
> as.numeric(dt.bris )
[1] 1325419200
>
<<p> 差异/em> > dt.est - dt.def
Time difference of 15 hours
> dt.est - dt.bris
Time difference of 15 hours
> dt.bris - dt.def
Time difference of 0 secs